Can I avoid the object variable name in ng-repeat loop?
angularjs, angularjs-ng-repeat, angularjs-scope, javascript
Solution
I've decided to combine the informative answers of Mathew Berg and ganaraj with my newfound knowledge to create a helpful answer to this.
The short answer is You really don't want to do that.
The longer answer is this:
When using `ng-repeat="block in blocks`" , a new scope is created for each block element, and the properties of every block object are create in `scope.block` of each block. This is a good thing, because this means all properties can be accessed by reference, updated or $watched.
If `ng-repeat` wouldn't have done that, and all properties would just be slapped unto the block's scope, then all primitives in `block` (strings, ints, etc) would just be copied from the block object to the block scope object. A change in one will not reflect on the other, and that's bad. More info on that here.
Ok so now that we've decided that's a good thing rather than a bad thing, how do we overcome the semantic issue? I've decided to use the `friendData` object container as the object on the scope of my directive, and so the directive expects the `friend-data` attribute to hold the relevant properties
angular.module('myApp',[])
.directive("lookActions", function(){
return {
restrict: 'E',
template: "<input value='Kill -{{ friendData.name }}-' type='button'>",
scope : {
friendData : '='
}
}
});
This way I can assign this object regardless of which context I'm calling my directive template.
Given these controller contexts:
function gridCtrl($scope) {
$scope.blocks = [{ type: "cat", name: "mitzi"},{ type: "friend", name: "dave"},{ type: "guitar", name: "parker"}];
}
function friendCtrl($scope) {
$scope.data={
name: "dave"
}
}
How to call the directive -
Within an `ng-repeat`:
<div class="block" ng-repeat="block in blocks" >
<look-actions friend-data="block" />
</div>
Or in a difference context:
<div ng-controller="friendCtrl">
<look-actions friend-data="data" />
</div>
Here's the solution Fiddle
Thanks for all the help!
Problem
When defining an ng-repeat directive to iterate over an array, the syntax specifies `ng-repeat="friend in friends"`, and then within the template you use the interoplation operator like so `{{friend.name}}`. Is it possible to have the properties assigned to the current item scope, rather than a variable in it? So I could call just `{{name}}` instead of `{{friend.name}}`? The reason being is that my directive is being used in the scope of two different templates - for example I might have a directive `"userActions"` that is used in both a repeater, and also inside an unrelated template where `{{friend.name}}` doesn't make sense. I would like to avoid artificially manufacturing the `friend` object where it doesn't have a semantic meaning. My use case is something like this: I have a grid that renders blocks of various types. Some psuedo code: ``` <div ng-repeat="block in blocks"> < cat block /> < friend block > <userActions directive /> </ friend block > < guitar block /> .... more blocks </div> ``` I also have a friend page, that contains the exact same user actions: ``` ..fragment of friend page.. <element ng-control="friend"> <userActions directive /> </element> ``` Now, if I want to user a property of the block inside the repeater, the syntax is `{{block.name}}`. So the template for `userActions` contains this. However, once I use this template in the friend page, I must create `{{block.name}}` inside the scope of the friend controller. This does not make sense though, because the block only exists in the context of the block grid. I shouldn't have to create this `block`. What I want to be able to do, is just to call `{{name}}` from within the `userActions` directive template, since both the block scope and the controller contain it. I don't want to create a `block` object, then artificially set `block.name` in each scope where I want to use the `userActions` directive. Here's a jsFiddle to illustrate the cause