Why don't AngularJS filters work if inside ng-if?

I have a simple AngularJS page with different sections that I show and hide when clicking links. One of these areas has a duplicate list that can be filtered.

When a section containing a list is displayed / hidden using ng-show or ng-hide , it behaves normally. When ng-if , the list cannot be filtered.

Demos


HTML example

 <nav> <a href="javascript:{}" ng-click="area='one';">Area 1</a> <a href="javascript:{}" ng-click="area='two';">Area 2</a> </nav> <div ng-if="area==='one'"> <h3>Area 1!</h3> <input type="text" placeholder="filter list..." ng-model="filterText" /> <ul> <li ng-repeat="item in list | filter: listFilter"> {{item.id}} - {{item.name}} </li> </ul> </div> <div ng-if="area==='two'"> <h3>Area 2!</h3> <p>Stuff here...</p> </div> 

Angular example

 $scope.area="one"; $scope.filterText=""; $scope.list = [ {id:1, name:"banana"}, {id:2, name:"apple"}, {id:3, name:"orange"}, {id:4, name:"pear"}, {id:5, name:"apricot"} ]; $scope.listFilter = function(item){ var term = $scope.filterText.trim().toLowerCase(); return item.id.toString().indexOf(term) > -1 || item.name.indexOf(term) > -1; }; 
+8
angularjs angular-filters
source share
1 answer

I do not have a master's degree in Prototypal Inheritance, but I will try my best to explain this in the near future (there are many resources on this subject);

  • Number
  • String
  • Boolean
  • null
  • undefined
  • Symbol (with ES6)

primitives (MDNs) are considered.

Now — when you inherit a “primitive” from your parent area, what is actually happening is that the child area “mirrors” or “shadows” the given primitive value. So you can see this as a copy of the above.

This is roughly the nature of primitives in the context of prototype inheritance.

This can be clearly seen in the modified version of your broken violin .

Try playing with two inputs, and you will see that there is a connection of two values ​​when you touch only the external input (that is, the child value of the "shadow" of the parent value). But as soon as you touch the internal input, the values ​​are disconnected from each other.


the recommended way to get around this is to use a property reference on your model (I say the model, but it's really just a JS object), which is defined later in the prototype chain;

 $parentScope.obj = { filterText: '' }; ng-model="obj.filterText" 

Now it will be nice for you to go with ngIf , ngSwitch , ngRepeat , to name a few of the angular supplied directives that create a new scope.

Related Resources

+2
source share

All Articles