Reputation: 191
I am trying to read properties set on an element by ng-repeat
using another custom element:
<div foo ng-repeat="img in [{image: 'images/img1.jpg', text: 'some text'},{image: 'images/img2.jpg', text: 'some text'}]">
<img ng-src="{{img.image}}"/>
<p>{{img.text}}</p>
</div>
app.directive('foo',function() {
return {
restrict : 'A',
scope: {},
link:function (scope, element, attrs) {
var imageNode = element.find('img');
var textNode = element.find('p');
var image = {
url: imageNode.prop('src'),
text: textNode.html()
};
console.log(image);
}
};
});
Since the ng-repeat
runs before the custom directive, the DOM should be inserted with the 2 elements by the time the link function of 'foo' kicks in. In such case, the link function of 'foo' should fire twice with element as the inserted DOM by ng-repeat.
The problem is that imageNode.prop('src');
has the value "{{img.image}}" and not the evaluation of the expression.
Can anyone help me understand what exactly is happening under the hood.
Plunker example - https://plnkr.co/edit/E9JHhZUf2h7B6FVeXRK4?p=preview
EDIIT
The example above is trivial but what i wanted to understand is the flow of the directive execution. There are ways of getting the data to the foo directive but that's not the final objective.
According to my understanding, since ng-repeat and foo are defined on the same element, the execution order will be
1) compile of ng-repeat because ng-repear has a priority of 1000
2) compile of foo since foo has a default priority of 0
3) link of foo since link executes in reverse priority order
4) link of ng-repeat
since ng-repeat uses transclude, it sucks out the DOM during the compile phase and is added again during its link phase.
If that is the case, the link function of foo that is executing before link of ng-repeat should have nothing but the comment inserted by transclude as its element as the DOM is not yet added. But that's not the case. I can access the two newly added DOM elements added by ng-repeat in foo's link phase. What am i missing?
Also, if i am not wrong, the expressions are evaluated during the link phase, so if the new elements are reinserted by ng-repeat which happens during link phase, the expressions should have also been evaluated and the {{img.text}} should have been converted to "some text" during the link phase of ng-repeat which is not happening but when i do element[0] that is i can see the value {{image.text}} being replaced. Am i again missing something?
Upvotes: 1
Views: 1876
Reputation: 1895
If you want to pass the data of the repeat to an attribute and use it in the directive try like this
<div foo imgdata="img" ng-repeat="img in [{image: 'images/img1.jpg', text: 'some text'},{image: 'images/img2.jpg', text: 'some text'}]">
<img ng-src="{{img.image}}" />
<p>{{img.text}}</p>
</div>
app.directive('foo',function(){
return{
restrict : 'A',
scope:{
imgdata: '='
},
link:function(scope,element,attrs){;
console.log(scope.imgdata);
}
}
});
this fiddle shows the way
hope this helps
Upvotes: 0
Reputation: 14216
If you're simply trying to pass in the url and text, why not just add them to the scope?
just change the html to :
<div foo text={{img.text}} image-url={{img.image}} ng-repeat="img in [{image: 'images/img1.jpg', text: 'some text'},{image: 'images/img2.jpg', text: 'some text'}]">
and the dierctive to :
app.directive('foo',function(){
return{
restrict : 'A',
scope:{
text: '@',
imageUrl: '@'
},
link:function(scope,element,attrs){;
console.log(scope.text);
console.log(scope.imageUrl);
}
}
});
see modified plunkr : https://plnkr.co/edit/0gw7uom9BGjFGJQ9e20E?p=preview
Upvotes: 0
Reputation: 6403
you can pass image data in directive as attribute
<div foo data='obj' ng-repeat="img in [{image: 'images/img1.jpg', text: 'some text'},{image: 'images/img2.jpg', text: 'some text'}]">
<img ng-src="{{img.image}}" />
<p>{{img.text}}</p>
</div>
app.directive('foo',function(){
return{
restrict : 'A',
scope:{},
link:function(scope,element,attrs){;
var image = {};
image.url = attrs.data.image
image.text = attrs.data.text
console.log(image);
}
}
});
Upvotes: 1