应该记住:
Angular的数据绑定依赖于JavaScript的原型继承,因此会受到可变阴影的影响。
子作用域通常从其父作用域继承原型。该规则的一个例外是指令,该指令具有隔离的范围,因为它不典型地继承。
有一些特殊指令,创建一个新的子范围:ng-repeat,ng-switch,ng-view,ng-if,ng-controller,ng-include,等。
这意味着当您尝试将某些数据双向绑定到子作用域内的原语时(反之亦然),事情可能无法按预期进行。这是一个“轻松”破坏AngularJS的示例。
通过执行以下步骤可以轻松避免此问题:
有一个 ”。” 在您绑定一些数据时在HTML模板中
使用controllerAs语法,因为它促进了对“点状”对象的绑定的使用
$parent可用于访问父scope变量而不是子范围。像里面ng-if我们可以使用ng-model="$parent.foo"..
上面的一种替代方法是绑定ngModel到一个getter / setter函数,该函数将在使用参数调用时更新模型的缓存版本,或在不使用参数调用时返回模型的缓存版本。为了使用getter / setter函数,您需要添加ng-model-options="{ getterSetter: true }"具有ngModal属性的元素,如果要在表达式中显示其值,则需要调用getter函数(工作示例)。
视图:
<div ng-app="myApp" ng-controller="MainCtrl"> <input type="text" ng-model="foo" ng-model-options="{ getterSetter: true }"> <div ng-if="truthyValue"> <!-- I'm a child scope (inside ng-if), but i'm synced with changes from the outside scope --> <input type="text" ng-model="foo"> </div> <div>$scope.foo: {{ foo() }}</div> </div>
控制器:
angular.module('myApp', []).controller('MainCtrl', ['$scope', function($scope) { $scope.truthyValue = true; var _foo = 'hello'; // 这将用于缓存/表示'foo'模型的值 $scope.foo = function(val) { // 当使用零参数调用时,该函数返回内部的'_foo'变量, // 并在使用参数调用时更新内部的_foo returnarguments.length? (_foo = val) : _foo; }; }]);
最佳实践:最好保持快速的getter,因为Angular调用它们的频率可能比代码其他部分(参考)更高。