Search code examples
angularjsangularjs-directiveangularjs-ng-repeatjquery-jscrollpane

Nesting Custom Directive with ng-repeat


i'm a newcomer with AngularJS,

i'm trying to create a custom directive that applies jQuery JScrollPane (JScrollpane.kelvinluck.com) to a div.

i have the following html code:

<scrollPane> ------> WRONG
<div scroll-pane> -----> RIGHT
    <ul>
        <li data-ng-repeat="task in tasks">
            <div class="task-element">
                <div class="name">{{task.display_name}}</div>
                <div class="text">{{task.min_description}}</div>
            </div>
        </li>
    </ul>
</scrollPane>

and the following directive:

angular.module('myApp', []).directive('scrollPane',function() {
return {
    restrict:'A',
    template: '<div></div>',
    link: function (scope, elm, attrs) {
    console.log("in directive");
    element.addClass('scroll-pane');
    element.jScrollPane({showArrows: true,autoReinitialise:true });
}};
});

the main issue is that the template's html overwrites the entire <scrollPane> element and the ng-repeat <li> is not displayed at all and get deleted from the final html.

what it the right way of creating the directive to wrap the inside html with an html (in my example it will be div and class='scroll-pane' ), and where should I insert the : $('.scroll-pane').jScrollPane(); ?

Thanks for the helpers.

Update: well the above code turned to be not working, the problem was in the HTML , since the directive should be with a restrict:"A" in the directive. ( thanks to http://www.befundoo.com/university/tutorials/angularjs-directives-tutorial/ tips)

to apply the jScrollPane, i just used inside the directive

element.jScrollPane({showArrows: true,autoReinitialise:true }); 

everything got working for me, but i have one issue open: for some css workaround i have to get the length of tasks in the ng-repeat to set a fixed height for the div. while i was debugging i saw that it not rendered yet, how is it possible, to wait until ng-repeat gets it data ? (using a service).


Solution

  • Maybe you're looking for the transclude function

    angular.module('myApp', []).directive('scrollPane',function(){
    return {
        restrict:'E',
        transclude: true,
        template: '<div class='scroll-pane' ng-transclude></div>',
        link: function (scope, elm, attrs) {
            console.log("in directive");
        }
    };
    });
    

    this will put the contents of <scroll-pane> in the div of your template.

    I'm not sure about where to put$('.scroll-pane').jScrollPane(); Probably in the link function and with angular.element(jquery selector here) , the angular wrapper. the link function in the directive definition object is actually a post-link function and it'll run after the DOM is modified. it's the safe place do do extra DOM modifications.

    edited: some parts of this answer don't match current version of the question. for example, restrict: 'E'