Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot find elements within directive templateUrl, in link function

Here is my directive code:

// Generated by CoffeeScript 1.6.3
(function() {
  var autumnDirectives;

  autumnDirectives = angular.module('autumnDirectives', []);

  autumnDirectives.directive('timeline', function() {
    return {
      scope: {
        timeline: '='
      },
      templateUrl: 'partials/timeline/_timeline.html',
      controller: function($scope, $element, $attrs) {
        return console.log($scope.timeline);
      },
      link: function(scope, el, attrs) {
        console.log(el);
        return console.log(el.find(".item"));
      }
    };
  });

}).call(this);

my template:

<div class="timeline clearfix">
    <div class="item" ng-repeat="item in timeline">
        <div class="row">
            <div class="content">{{ item.content }}</div>
        </div>

        <div class="row">
            <div class="connect_line"></div><div class="connect_line"></div>
        </div>
    </div>
</div>

For some reason the jqlite find does not return the item element (length 0) -or any element for that matter. If I append an element in the link function then I am able to find it, however otherwise no.

When I log el, it returns the correct element, and if I venture into children with chromes inspect tool I am able to find .item.

I thought that link was called once the template was ready? Is something going wrong here, or am I not understanding something?

Otherwise everything works fine

Thanks

NOTE: I am able to find the first div in the hierarchy with the .timeline class, but nothing at a deeper level

like image 631
Melbourne2991 Avatar asked Jan 22 '14 13:01

Melbourne2991


Video Answer


2 Answers

You should run it inside $timeout:

$timeout(function(){
  console.log(el.find(".item"));
})

What happens is that ngRepeat registers a $watchCollection with a callback.
When a $digest happen , that callback clones the DOM elements. Before that $digest no DOM elements are available. $timeout run after a $digest so we can safely refer the DOM elements.

I made a plunker to check when elements are loaded to the DOM : http://plnkr.co/edit/X8PuOQhhbQB3Gv657R35?p=preview

like image 112
Ilan Frumer Avatar answered Sep 30 '22 03:09

Ilan Frumer


You're generating your .item with ng-repeat. At the time, ng-repeat directive is not finished rendering.

At that time, the HTML looks like this: (using console.log(el[0].outerHTML))

<div timeline="" class="ng-isolate-scope">
   <div class="timeline clearfix">
     <!-- ngRepeat: item in timeline -->
   </div>
</div>
like image 20
Khanh TO Avatar answered Sep 30 '22 03:09

Khanh TO