Reputation: 13479
Given this test case using AngularJS 1.2 rc3: http://plnkr.co/edit/MX6otx (repeated below)
1.
<li ng-init="toggle1 = false">
ng-if toggle1: {{ toggle1 }}
<p>
<button ng-if="!toggle1" ng-click="toggle1 = true">Turn On</button>
<button ng-if="toggle1" ng-click="toggle1 = false">Turn Off</button>
does not work
</li>
2.
<li ng-init="obj={toggle2:false}">
ng-if obj.toggle2: {{ obj.toggle2 }}
<p>
<button ng-if="!obj.toggle2" ng-click="obj.toggle2 = true">Turn On</button>
<button ng-if="obj.toggle2" ng-click="obj.toggle2 = false">Turn Off</button>
then why does this work?
</li>
Questions:
Upvotes: 34
Views: 27509
Reputation: 691755
This scope inheritance mechanism is explained very well in https://github.com/angular/angular.js/wiki/Understanding-Scopes
Upvotes: 28
Reputation: 29897
1. Why does 1 not work?
ng-if
creates a new scope. which causes the "weird" binding behavior as explained in this video: http://egghead.io/lessons/angularjs-the-dot
2. Should 1 work?
Reading properties from the parent scope works (prototype chain), but writing to the scope creates a new property on the child scope. Creating a disconnected
3. Why does 2 work?
The same property is read from the parent scope (obj). The write in ng-click changes the "obj" object, not the scope.
4/5. Should 2 work? Can I rely 2 to work in future updates of AngularJS?
YES, this is the documented expected behavior.
Tip: I use the Chrome extension AngularJS Batarang to gain insights about which variables are on which scope.
Upvotes: 4
Reputation: 77904
Since ngIf
creates own scope, to make it work you can define toggle1
in one scope:
JS**
$scope.toggleMe = function(){
$scope.toggle1 = !$scope.toggle1;
}
HTML
<li ng-init="toggle1 = true">
ng-if toggle1: {{ toggle1 }}
<p>
<button ng-if="toggle1" ng-click="toggleMe()">Turn On</button>
<button ng-if="!toggle1" ng-click="toggleMe()">Turn Off</button>
does not work
</li>
See Demo Plunker
Upvotes: 5