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!
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.
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
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();
}
};
}])
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:'='}
}
})