Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to apply jquery after AngularJS partial template is loaded

I have a simple website that implements jQuery in order to create a Slider with some images in the Index.html top banner.

Now, I want to use AngularJS so I'm breaking the HTML code into separate partials.

  1. Header
  2. Footer
  3. Top Banner

If I run the Index.html in the original version (without applying AngularJS patterns) then I can see the slider working perfect.

When applying AngularJS patterns, I moved the top banner HTML to a partial html and then applied ng-view to the div where the top banner is originally located.

var app = angular.module('website', ['ngRoute']);
app.config(function($routeProvider) {
    $routeProvider.
    when('/about',{templateUrl:'app/partials/about.html'}).
    when('/contact',{templateUrl:'app/partials/contact.html'}).
    otherwise({redirectTo:'/home',templateUrl:'app/partials/home.html'})
});

When I refresh the page the slider is not working, is rendered as simple html without any jQuery effect, is really a mess.

This partials has some jQuery plugins that usually activates by document.ready. But this event not fire when angular load partial in ng-view. How can i call this event to initialize jQuery plugins?

Any clue how to fix this?

Appreciate any help.

like image 922
VAAA Avatar asked Mar 08 '14 21:03

VAAA


3 Answers

When you specify your routes, you can also specify a controller, so your routes would look like this:

var app = angular.module('website', ['ngRoute']);
app.config(function($routeProvider) {
    $routeProvider.
        when('/about',{templateUrl:'app/partials/about.html', controller: 'aboutCtrl'}).
        when('/contact',{templateUrl:'app/partials/contact.html', controller: 'contactCtrl'}).
        otherwise({redirectTo:'/home',templateUrl:'app/partials/home.html', controller: 'homeCtrl'})
    });

Now, you can define inside each controller what you want to do, jquery-wise, as part of a function, like this:

angular.module('website').controller('aboutCtrl', ['$scope', function ($scope) {

   $scope.load = function() {
       // do your $() stuff here
   };

   //don't forget to call the load function
   $scope.load();
}]);

Make sense?

like image 118
Aaron Avatar answered Oct 02 '22 18:10

Aaron


The other provided answers will work, but they are bound to controllers, and therefore not as scalable and reusable.

To do it the real "Angular" way as mentioned in the comments, you should be using a directive. The benefit to this is that you're able to create several instances with the same code, and can pass in attributes to the directive logic to "customize" the directive. Here's a sample of a way I've used it using bxSlider plugin:

JS:

app.directive('slider',  ['$rootScope', function($rootScope) {
return {
    restrict: 'EA',
    templateUrl: '/path/to/template',
    link: function(scope, iElement, attrs) {
        //attrs references any attributes on the directive element in html

        //iElement is the actual DOM element of the directive,
        //so you can bind to it with jQuery
        $(iElement).bxSlider({
            mode: 'fade',
            captions: true
        });

        //OR you could use that to find the element inside that needs the plugin
        $(iElement).find('.bx-wrapper').bxSlider({
            mode: 'fade',
            captions: true
        });

       }
    };
}]);

HTML:

<div slider some-attibute="some-attribute"></div>

And inside your directive template you could have the slider wrapper and slides, which you could build dynamically using ng-repeat bound to scope data.

I'd recommend reading this excellent article by Dan Wahlin about creating custom directives and how to fully harness they're power.

like image 45
Sean Thompson Avatar answered Sep 28 '22 18:09

Sean Thompson


I had the same problem, I was loading some nav links in a ng-include and I have a script file called on my index.html with jquery instructions to make links active and It i not see the included content.

I tried all of the above solutions and for some reasons, none of them worked for me. When the content is not included (straight in the index.html) jquery kicks in fine but once included it stopped recognizing my elements.

So I simply wrapped my instructions in a setTimeout() function and it worked! Maybe it'll work for you too?

setTimeout(function() {
    $("nav ul li").click(function() {
        $("nav ul li").removeClass('active');
        $(this).addClass('active');
    });
});

Somehow the setTimeout() manages to load the script AFTER angular is done loading included content.

Happy coding everyone !

like image 36
Maranaho Avatar answered Oct 01 '22 18:10

Maranaho