nosthertus nosthertus - 1 month ago 25
AngularJS Question

Angularjs: slick not working properly with custom directives

i have been trying for hours looking for a method to make a carousel to slide multiple elements instead of one, but elements that are compiled custom directives from

angularjs
, for the moment i found
slick
is the good framework that can do this job and i have tested on my local files with successful results, but when i try to load it to the server which has everything loading from cdn, browser starts to throw errors multiple times:

Error: a.replace is not a function
Error: w is undefined
Error: a.replace is not a function
Error: w is undefined


the code the page has.. is like this:

<!DOCTYPE html>
<html>
<head>
<title>styles</title>
<meta charset="utf-8">

<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.css">
<link href="https://fonts.googleapis.com/css?family=Raleway:300,400" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/jquery.slick/1.6.0/slick.css">
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body ng-app="test" ng-controller="testController" layout="column" layout-fill>
<md-content flex layout="column">
<md-content flex>
<div class="focusPlan">
<div class="focus">
<p>Focus</p>
</div>
<div class="plans">
<card-plans button="Get"></card-plans>
<card-plans button="Get"></card-plans>
<card-plans button="Get"></card-plans>
<card-plans button="Get"></card-plans>
<card-plans button="Get"></card-plans>
<card-plans button="Get"></card-plans>
</div>
</div>
<div class="focusPlan">
<div class="focus">
<p>Focus</p>
</div>
<div class="plans">
<card-plans button="Get"></card-plans>
<card-plans button="Get"></card-plans>
<card-plans button="Get"></card-plans>
<card-plans button="Get"></card-plans>
<card-plans button="Get"></card-plans>
<card-plans button="Get"></card-plans>
</div>
</div>
<div class="focusPlan">
<div class="focus">
<p>Focus</p>
</div>
<div class="plans">
<card-plans button="Get"></card-plans>
<card-plans button="Get"></card-plans>
<card-plans button="Get"></card-plans>
<card-plans button="Get"></card-plans>
<card-plans button="Get"></card-plans>
<card-plans button="Get"></card-plans>
</div>
</div>
<div class="focusPlan">
<div class="focus">
<p>Focus</p>
</div>
<div class="plans">
<card-plans button="Get"></card-plans>
<card-plans button="Get"></card-plans>
<card-plans button="Get"></card-plans>
<card-plans button="Get"></card-plans>
<card-plans button="Get"></card-plans>
<card-plans button="Get"></card-plans>
</div>
</div>
</md-content>
</md-content>

<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.jquery.com/jquery-migrate-3.0.0.min.js"></script>
<script src="//cdn.jsdelivr.net/jquery.slick/1.6.0/slick.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-animate.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-aria.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-messages.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.js"></script>

<script src="../cards/people/people-directive.js"></script>
<script src="../cards/plans/plans-directive.js"></script>
<script src="../cards/events/events-directive.js"></script>
<script src="../sections/blogs/blogs-directive.js"></script>
<script src="../sections/posts/posts-directive.js"></script>

<script>
/*
* Angular's application instance
*/
(function(angular, $){
var app = angular.module("test", ["ngMaterial", "test-directives"]);

app.config(["$mdThemingProvider", "$mdIconProvider", function($mdThemingProvider, $mdIconProvider){
$mdThemingProvider.theme('default')
.primaryPalette('light-blue',{
'default':'400'
});

$mdIconProvider.defaultIconSet("mdi.svg");
}]);

app.controller("testController", ["$scope", "$mdSidenav", function($scope, $sidenav){
$scope.toggleMenu = function(){
$sidenav("menu").toggle();
};

$(".plans").slick({
infinite: true,
slidesToShow: 3,
slidesToScroll: 3
});

$scope.gridMode = false;
}]);
})(angular, $);
</script>
</body>
</html>


in this view i only have 1 custom directive called multiple times which is
<card-plans>
and it actually contains little logic with template.

without slick the items look like this:
directive list

and all i want is just to have a carousel to scroll multiple elements instead of 1 by 1

Answer

Seems like kind of init sequance problems.

Wrap your slick logic into separate directive with transclusion using postlink function

.directive('carousel', function(){
    return function(){
        restrict: 'E',
        transclude: true,
        link: function(scope, el, attrs, ctrl, transclude) {
            el.append(transclude());
            elem.children().slick(/*stuff*/);
            scope.$on('$destroy', function(){/* slick destroy*/});
        }
    };
});

<carousel>
   <card-plans></card-plans>
   ....
</carousel>