How to initiate MixItUp with AngularJS NgRoute
Asked Answered
M

4

6

I've been setting up a jquery plugin MixItUp with AngularJS and although I can successfully initiate the container during one of my partial views with NgRoute, once I move to other page views and go back it seems that MixItUp does not know how to initiate setup again.

I’ve tried $(document).ready(), $(window).load, and even $viewContentLoaded but nothing seems to make it work. The whole container simply does not get called when I click on my other pages and return again.

My code as below.

$scope.$on('$viewContentLoaded', function(){  

    $('#container').mixItUp();    

    var $container = $('#ContainerP');

    if(!$container.mixItUp('isLoaded')){
      $container.mixItUp();
    } 
  alert("It's loading!");
});

Everything in the function passes smoothly including the alert message, but somehow mixItUp cannot be called within my routing views…would appreciate greatly if someone could help me out here! Thanks!

Minima answered 6/10, 2014 at 14:12 Comment(2)
Did you try to re-run a digest with $scope.$apply() command ?Demoss
Nevermind, I have made a switch to using isotope for my sort & filter grid logic and it worked perfectly with my Angular routing. It seemed for mixItUp it is dependent on the DOM updates triggered from the base route and hence I was not able to re-trigger it again in my partial views. Thanks anyways~Minima
H
1

As @demkalkov suggest use a directive and load mix-it-up related html as template like

.directive('mixItUp', function(){
    return{
      restrict: 'AEC',
      templateUrl: 'mix-it-up-tpl.html',
      link: function(scope, element){             
         $(element).mixItUp();
      }
    }
  })

Use the directive in html as

<div mix-it-up></div>

And lets say your mix-it-up.html looks like

<div id="Container" class="container">
  <div class="mix category-1" data-myorder="1"></div>
  <div class="mix category-1" data-myorder="2"></div>
</div

Here is a working Demo

Note - In Angular context directive is the ideal place to manipulate html or plugin integration.

Haemolysis answered 19/10, 2015 at 10:16 Comment(0)
A
1

I integrated jQuery MixItUp with AngularJS NgRoute with the use of a custom directive.

I use the AngularJS $broadcast and $on functions to handle communication between Controller and Directive:

myApp
.directive('mixitup', function($compile) {

    return {
        restrict: 'A',
        link: function(scope, element, attrs) {

            scope.$on('init-mixitup', function(event) {
                // console.log('[event] înit-mixitup');
                angular.element(element).mixItUp({
                    animation: {
                        duration: 200
                    },
                    load: {
                        sort: 'myorder:desc'
                    }
                });
            });

            scope.$on('resort-mixitup', function(event, sortCommand) {
                // console.log('[event] resort-mixitup');
                angular.element(element).mixItUp('sort', sortCommand);
            });

            scope.$on('destroy-mixitup', function(event) {
                // console.log('[event] destroy-mixitup');
                angular.element(element).mixItUp('destroy');
            })
        }
    };
});

My view HTML:

<div class="btn-group controls">
    <button class="btn btn-lg filter"
        data-filter="all">All</button>
    <button class="btn btn-lg filter"
        data-filter=".photo">Photo</button>
    <button class="btn btn-lg filter"
        data-filter=".audio">Audio</button>
    <button class="btn btn-lg filter"
        data-filter=".video">Video</button>
</div>

<div mixItUp="mixItUp" id="mixitup-container">
    <div ng-repeat="item in items"
        id="{{ item.id }}"
        style="display: inline-block;"
        data-myorder="{{ item.date }}"
        class="mix col-xs-6 col-sm-4 {{ item.category }}">
            <img ng-src="{{ item.image }}" class="img-responsive img-circle">
    </div>
</div>

In my controller handle jQuery MixItUp with the following calls:

// instantiate jQuery MixItUp
$rootScope.$broadcast('init-mixitup');

// sort jQuery MixItUp
$rootScope.$broadcast('resort-mixitup', 'myorder:desc');

You have to destroy jQuery MixItUp when leaving page. I managed this by adding the following to my controller:

$scope.$on("$destroy", function(){
    $rootScope.$broadcast('destroy-mixitup');
});

You can also have a look at a very similar question i posted myself: jQuery MixItUp with AngularJS NgRoute

Ashjian answered 11/11, 2015 at 13:37 Comment(0)
H
0

I'd recommend you to use directives when you are working with DOM. So you need to create some directive that will initiate MixItUp for you

angular.module('app').directive('myNgMixitup', [function(){
   return {
      restrict: 'AEC',
      link: function(scope, element){
         //now you can access the element/container
         element.mixItUp();
      }
   };
}])
Haskins answered 19/10, 2015 at 8:55 Comment(0)
V
0

I spent several hours and finally the solution is here....

if ($('#grid').mixItUp('isLoaded')) {
          $('#grid').mixItUp('destroy');
          $('#grid').mixItUp();
      } else {
        $('#grid').mixItUp();
      }

Here's the full directive code..

'use strict';
 angular.module('rjApp')
.directive('mixitup',function($timeout,$compile){
  var linker = function(scope,element,attr) {

    scope.$watch('entities', function(newVal, oldVal){

      $timeout(function(){
        if ($('#grid').mixItUp('isLoaded')) {
            $('#grid').mixItUp('destroy');
            $('#grid').mixItUp();
        } else {
          $('#grid').mixItUp();
        }
      },10);
    },true);

  };
  return {
    link: linker,
    scope:{entities:'='}
  }
})
Vinita answered 4/4, 2016 at 20:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.