Coded Container
Coded Container

Reputation: 863

How can you run a Javascript on a new AngularJS view

I am using routes in AngularJS which displays a different view based on the parameter, i.e URL parameter provided. I have a view that displays a slick slider. Unfortunately, the slider is not being instantiated or ran when the new view is displayed. How can I have this javascript run when the new view is displayed? Do I need to create a new directive?

AngularJS:

angularApp.config(['$routeProvider',
  function($routeProvider) {
    $routeProvider.
    when('/',
    {
        templateUrl:'/pages/default.html'
    }).
    when('/:params',
     {
        templateUrl: function(params){    
            params.param = params.params.replace(':', ''); 
            return '/pages/'+params.param; }

     });
}]);

Slick Slider JS:

$(window).load(function(){
  $('.slickSlider').slick({
    slidesToShow: 4,
    arrows: true,
    infinite: true,
    autoplay: true, 
    slidesToScroll: 1
  });

Upvotes: 0

Views: 83

Answers (4)

jherax
jherax

Reputation: 5267

I performed some refactoring to the code, in order to provide more semantic and clearness.

When the view is loaded, it emits the event: $viewContentLoaded meaning the DOM is loaded, then you can initialize jQuery plugins safely.

angularApp.config(['$routeProvider',
  function Router($routeProvider) {
      'use strict';

      $routeProvider
      .when('/:params', {
          templateUrl: function(params) {
              params.param = params.params.replace(':', '');
              return '/pages/' + params.param;
          },
          controller: 'ParamsCtrl',
          controllerAs: 'paramsCtrl'
      });
  }
]);

angularApp.controller('ParamsCtrl', ['$scope',
  function ParamsCtrl($scope) {
      'use strict';

      var paramsCtrl = this, //the controller
          $ = jQuery; //safe alias to jQuery

      //if your content is inside ng-include, 
      //use: $scope.$on('$includeContentLoaded')
      //emitted every time the ngInclude content is reloaded
      $scope.$on('$viewContentLoaded', function() {
          $('.slickSlider').slick({
              slidesToShow: 4,
              arrows: true,
              infinite: true,
              autoplay: true,
              slidesToScroll: 1
          });
      });
  }
]);

Check this useful answer: AngularJS Partial HTML not able to use jquery lib

Upvotes: 0

Coded Container
Coded Container

Reputation: 863

All you need to do is create an initialization function within your controller. Below is an example of what this would look like. When the view is initialized it called the controller in which the $scope function is called and your plugin JS code can run.

=== AngularJS ===

angularApp.controller('blog', function($scope){
    $scope.init = function()
    {
        $('.slickSlider').slick({
            slidesToShow: 4,
            arrows: true,
            infinite: true,
            autoplay: true, 
            slidesToScroll: 1
          });
    }
    $scope.init();

});

=== HTML ===

<div ng-controller="blog"></div>

Upvotes: 0

Ziv Weissman
Ziv Weissman

Reputation: 4526

Generally speaking- it is not recommended to combine jQuery & Angular when it comes to loading sequence... it is a bit messy. Better use one of them.

For your specific problem, I'd use the 'controller as', seen in this SO topic and on the controllers init, to call the functions you want.

Upvotes: 1

Tennyson H
Tennyson H

Reputation: 1716

You can add a onload attribute to the ng-view element that you are using for the view.

e.g. <div ng-view onload='startSlider()'>

then refactor slick slider to just be

function startSlider(){
  $('.slickSlider').slick({
    slidesToShow: 4,
    arrows: true,
    infinite: true,
    autoplay: true, 
    slidesToScroll: 1
  };

Upvotes: 0

Related Questions