Reputation: 203
Let's say I have 2 directives: "parent" (i.e. table) and "child" (tr), I would like to be able to select child elements and keep the list of them in my parent directive (I think the controller is the only possible place, isn't it?). I'm handling click events to update the list stored in my controller and it works fine but I'd also like to keep "selected" class for selected items, but because the selection may also be changed by the controller of parent directive (and modifying the DOM in controller is "forbidden"), the only possibility I could think of is a watcher in my child directive.
Take a look at the example, please:
angular.module('App')
.directive('parent', function () {
return {
scope : {},
controller: function($scope) {
this.selectedItems = [];
}
}
}).directive('child', function() {
return {
require: '^parent',
link: function(scope, element, attrs, controller) {
scope.$watchCollection('controller.selectedItems', function() {
//add or remove 'selected' class here.
}
}
}
});
That doesn't work (the watcher event fires only when the array reference changes and not individual elements) and it doesn't seem to be designed correctly either, could you provide me with a better approach to that issue?
update:
Notice that controller.selectedItems
is modified in the controller, however the child directive does not seems to watch any change.
Upvotes: 3
Views: 49
Reputation: 2105
Pls see: How to deep watch an array in angularjs?
You should use $watch and set the third optional argument of $watch to true.
scope.$watch(function(){
return controller.selectedItems;
},
function() {
//add or remove 'selected' class here.
},
true
);
update:
Okay so you should also notify all application external watchers that a modification has took place. In AngularJS if a variable is modified by a controller but watched somewhere else and if there is not $digest or $apply the watcher does not see any change. So the problem was not the choice of the watcher, but the missing of an $apply command.
Simply add:
$scope.$apply();
in your controller after the alteration of the array.
Upvotes: 1
Reputation: 203
I fixed it with invoking $scope.$apply() after modifying the array in controller. Methods were triggered by javascript events so the digest loop was never run probably.
If anyone had other suggestions related to the above design, please let me know.
Upvotes: 2