34

鉴于这个使用 AngularJS 1.2 rc3 的测试用例:http: //plnkr.co/edit/MX6otx(下面重复)

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>

问题:

  1. 为什么1不起作用?
  2. 1应该工作吗?
  3. 为什么 2 有效?
  4. 2应该工作吗?
  5. 我可以依靠 2 在 AngularJS 的未来更新中工作吗?
4

3 回答 3

28
  1. 为什么 1 不起作用?:因为 ngIf 定义了自己的范围,该范围在原型上继承自其父范围(就像 ngRepeat 一样)。因此,当您更改 ngIf 内的字段值时,您会在 ngIf 范围内更改它,而不是在其父范围内。
  2. 应该 1 工作吗?:
  3. 为什么 2 起作用?:因为在这种情况下,您通过继承修改了 ngId 范围引用的对象的内容。
  4. 2应该工作吗?:是的
  5. 我可以依靠 2 在 AngularJS 的未来更新中工作吗?:为什么不呢?

这种范围继承机制在https://github.com/angular/angular.js/wiki/Understanding-Scopes中有很好的解释

于 2013-11-06T12:34:20.547 回答
5

由于ngIf创建了自己的范围,为了使其工作,您可以toggle1在一个范围内定义:

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>

看演示Plunker

于 2013-11-06T12:38:43.543 回答
4

1.为什么1不起作用?
ng-if创建一个新的范围。这会导致本视频中解释的“奇怪”绑定行为:http: //egghead.io/lessons/angularjs-the-dot

2. 1 应该工作吗?
从父作用域读取属性是可行的(原型链),但写入作用域会在子作用域上创建一个新属性。创建断开连接

3. 为什么 2 有效?
从父作用域(obj)中读取相同的属性。ng-click 中的写入会更改“obj”对象,而不是范围。

4/5。2应该工作吗?我可以依靠 2 在 AngularJS 的未来更新中工作吗?
的,这是记录在案的预期行为。

提示: 我使用 Chrome 扩展AngularJS Batarang来了解哪些变量在哪个范围内。

于 2013-11-06T12:35:02.727 回答