1

I have a problem trying to watch in my controller a collection generated by a filter in the view.

I store the filtered data in a variable :

 <table class="table">
     <tr ng-repeat="item in filteredCollection = (myCollection | filter: txtSearch)">
         <td ng-bind="item"></td>
     </tr>
 </table>

and I would like to subscribe to changes of 'filteredCollection ' in my controller :

$scope.$watchCollection('filteredCollection', function() {
    if (typeof($scope.filteredCollection) != 'undefined')
        console.log('Results changed : ' + $scope.filteredCollection.length);
});

I have set up this JSFiddle to show you my issue : my watch function is never called.

Fun Fact, it works when I remove all the <tabset> <tab> tags in my HTML. I think I messed up with the $scope, but I don't get why. Maybe the tabset create a new $scope child or something.

I hope you guys will find out what is going on here,

Cheers

3 Answers 3

1

Try to put filteredCollection in an object, so the it will change the correct scope property:

$scope.obj = { filteredCollection : [] };
$scope.$watchCollection('obj.filteredCollection', function(newVal) {
    if (typeof($scope.obj.filteredCollection) != 'undefined')
        console.log('Results changed : ' + $scope.obj.filteredCollection.length);
});

In the HTML:

<tr ng-repeat="item in obj.filteredCollection = (myCollection | filter: txtSearch)">

See this fiddle.

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

2 Comments

Thanks for your answer, but could you explain why I have to do that ? Is it a matter of variable passed by reference / value ?
thats because ngRepeat create a child scope, and then your filteredCollection will be a property on that scope. If you define an obj on the parent scope, then every change will be written to that parent scope. see this: github.com/angular/angular.js/wiki/Understanding-Scopes
1

You are correct in your thought that tabset and tab create new scopes. Because of that you are losing the context of filteredCollection since this is now being created in the context of the tab directives scope.

Angular fairly recently added controllerAs syntax that helps to avoid situations like this. It allows us to determine better which scope something is being executed in.

I have updated your jsFiddle with controllerAs syntax to show how this helps. The watch now fires as expected.

http://jsfiddle.net/hezwyjx1/2/

Here is a resource for some help with controller as syntax:

http://toddmotto.com/digging-into-angulars-controller-as-syntax/

1 Comment

Thank you for this interesting approach, I didn't know this "controllerAs" thing, and the article was great. But in my case, I find this solution 'heavier' than putting the collection in an object
0

This is an another post with the solution for this: https://github.com/angular-ui/bootstrap/issues/1553

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.