0

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 });
    }
};
}]);
2
  • A reproducable demo will be helpful Commented Oct 5, 2014 at 11:41
  • Filter it on demand, or use a watch on the unfiltered array. Commented Oct 5, 2014 at 11:59

1 Answer 1

1

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'.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.