Reputation: 99
I'm new to AngularJS. I've built a directive that uses an Isolate Scope (=) on an array called "todos". I then filter the todos array, and call it filteredArray. My "todos" element is updated using bidirectional binding, but I do not know what must be done to bind the update of todos to filteredArray.
I've set up a fiddle for my experimenting here: http://jsfiddle.net/apkk3rjc/ You can even see I've tried to set up a simple $watch() on line 50 of my JS but it doesn't seem to trigger beyond the first load.
To be clear: I don't need two-way binding back to my controller, but I do need the filteredTodos to update automatically when a change to todos is made.
Here is my directive:
todoApp.directive('todoList', ['filterFilter', function(filterFilter) {
return {
restrict: 'E',
templateUrl: 'todo-list.html',
scope: {
todos: '='
},
link: function (scope, element, attrs) {
// scope.todos is bound
// scope.filteredTodos is not!
scope.filteredTodos = filterFilter(scope.todos, { completed: false });
}
};
}]);
Upvotes: 0
Views: 869
Reputation: 99
I have found the answer to my own question. Two things need to be applied:
First, scope.filteredTodos won't be bound automatically, so it must be recalculated whenever scope.todos is modified. So we add a $watch to the array.
My original $watch looked like this and is wrong:
// Watch the entire array. DOESN'T FIRE ON NEW ITEMS
scope.$watch('todos', function () { ... });
This does not work because watching the entire array doesn't track changes. In the end, I simply watched the length of the array.
// Watch the array length. Works when new items are added! :)
scope.$watch('todos.length', function () { ... });
Alternatively, you can set a third parameter, 'deep' to true, but this comes with a lot of overhead, especially if your array is very large. However, if you want to watch each item of your array for changes, this will be the only way.
// Watch the entire array with deep analysis. Costly, but works.
scope.$watch('todos', function () { ... }, true);
So since I'm just looking for new elements in my array, I went with watching 'todos.length'.
Upvotes: 1