Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS: Linking to elements in a directive that uses ng-repeat

Tags:

I have a simple directive where the template uses ng-repeat inside it. I need to run some code to instantiate a jquery component against some of the elements created by the ng-repeat directive. The problem is that if I put this code in the link function. The ng-repeat hasn't built those elements yet so nothing is instantiated.

App.directive('myDirective', ['$compile', '$timeout', function($compile, $timeout) {   return {     scope: {         domains: '='     },     templateUrl: '/app/partials/my_directive.html',     link: function($scope, element, attributes) {         element.find('.standard-help').tooltip('destroy');         element.find('.standard-help').tooltip({placement: 'top', trigger: 'click hover focus'});     }   }; } 

The template would look like the following. I'm trying to attach

<ul class="media-list domainList">   <li class="media" style="position:relative;" ng-repeat="domain in domains">     <a class="domainHeader" href="javascript://">         <span class="domainHeader">{{domain.tag}}</span>     </a>     <div class="media-body" style="margin-left: 52px;">         <ul class="standardsList">             <li ng-class="{ standardDisplayed: lessonLayout == 'standards' }" ng-hide="standard.lessons.length == 0" ng-repeat="standard in domain.standards">                 <a href="javascript://" title="{{standard.description}}" ng-show="lessonLayout == 'standards'" class="standard-help pull-right"><i class="icon-question-sign"></i></a>                 <h6 ng-show="lessonLayout == 'standards'">{{standard.tag}}</h6>                 <ul class="lessonsList">                     <li ng-class="{ lesson: true }" ng-repeat="lesson in standard.lessons" ng-click="onLessonSelected(lesson)">                         <i class="icon-lock lesson-locked"></i>                         <div>{{lesson.title}}</div>                     </li>                 </ul>             </li>         </ul>     </div>   </li> </ul> 

I've tried using $watch() and $observe() to register a callback when the domains change and instantiate the tooltip code then. However, I can't seem to get it to call me at the right time. Any ideas what I'm missing?

like image 707
chubbsondubs Avatar asked Jul 14 '13 20:07

chubbsondubs


People also ask

What does this directive do in AngularJS does ng-repeat?

AngularJS ng-repeat Directive The ng-repeat directive repeats a set of HTML, a given number of times. The set of HTML will be repeated once per item in a collection. The collection must be an array or an object. Note: Each instance of the repetition is given its own scope, which consist of the current item.

How do I get the index of an element in NG-repeat?

Note: The $index variable is used to get the Index of the Row created by ng-repeat directive. Each row of the HTML Table consists of a Button which has been assigned ng-click directive. The $index variable is passed as parameter to the GetRowIndex function.

Which directive helps to create elements repeatedly?

The ng-repeat directive actually clones HTML elements once for each item in a collection.

What can I use instead of NG-repeat?

You can consider using transclusion inside a custom directive, to achieve the behavior you are looking for without using ng-repeat.


1 Answers

I found that if created another directive that I added to the element where the ng-repeat was being created it would be notified for each element the repeat created. Then I could simply $emit an event that the parent directive could listen for. At which point it could perform the linking to the repeated elements there. This worked quite nicely especially for multiple ng-repeats within the dom because I could separate them by their event type which would be passed to the new directive.

Here is my directive:

App.directive("onRepeatDone", function() {     return {         restrict: 'A',         link: function($scope, element, attributes ) {             $scope.$emit(attributes["onRepeatDone"] || "repeat_done", element);         }     } }); 

Here is the usage of that new directive in the template:

<ul>     <li on-repeat-done="domain_done" ng-repeat="domain in domains">...</li> </ul> 

Then inside the parent directive I could do the following:

link: function( $scope, element, attributes ) {     $scope.$on('domain_done', function( domainElement ) {         domainElement.find('.someElementInsideARepeatedElement').click(...);     } ); } 
like image 183
chubbsondubs Avatar answered Oct 01 '22 16:10

chubbsondubs