Reputation: 9428
In Angular 1.2, the element inside ngRepeat can see the parent scope's function(isConvoTabActive). However, after I switch to 1.3, this is no longer working. I checked the migration guide but found nothing. How can I fix this without using $parent.isConvoTabActive?
app.directive('myDirective',function(){
return {
restrict: 'E',
scope: {
},
controller: ["$scope", "$element", "$attrs",
function($scope, $element, $attrs) {
$scope.isConvoTabActive = function(convoId) {
return convoId == $scope.indexes.activeConvoId;
};
}
},
template: "<div ng-repeat='(convoId, convo) in convos'>" +
"<div ng-if='isConvoTabActive(convoId)'></div>" +
"</div>",
replace: true, // replace the directive element
link: function (scope, element, attrs) {
scope.indexes = {
"activeConvoId": "111"
};
scope.convos = {
"111": {
"title": "convo 111"
},
"222": {
"title": "convo 222"
}
};
}
}
})
EDIT1 I tried ng-show, it doesn't work either.
EDIT2 It works on Plunker. I'm not sure why. http://plnkr.co/edit/7pdp40CQzUqOISwXgN4u
:
Upvotes: 1
Views: 396
Reputation: 1457
OK, so this is an example of what I mean by using controller-as:
app.directive('myDirective',function() {
return {
restrict: 'E',
scope: {
indexes: '='
},
controllerAs: 'ctrl',
bindToController: true,
controller: function() {
var model = this;
model.isConvoTabActive = function(convo) {
return convo == model.indexes.activeConvo;
};
}
},
template: "<div ng-repeat='convo in ctrl.convos'>" +
"<div ng-if='ctrl.isConvoTabActive(convo)'></div>" +
"</div>"
}
});
I've added this as another answer as formatting and space was limited in comments. I'm aware that I don't know where some things are coming from or what they contain, e.g. where does 'convos' get bound to scope? That's why I think a plunkr would be helpful. I've also made a change discussed in the other answer: to just compare the object references rather than ID values (gets problematic when value types are copied down the scope inheritance chain).
Upvotes: 0
Reputation: 1457
As an alternative solution, which would be less refactoring, you could just use ng-show (as long as you have no problem with your element being hidden from the DOM rather than removed). ng-show doesn't create a child scope.
Upvotes: 2
Reputation: 1457
You could use the controller as syntax which will allow you to reference your model / controller explicitly. I don't have a link handy on my phone or fancy typing a code example but it should be easy enough to find.
The bindToController property (for your directive) is key to getting rid of the need for $scope. It will bind your directive attributes to the controller instance instead.
Upvotes: 0