AngularJS 双向数据绑定停止工作

示例

应该记住:

  1. Angular的数据绑定依赖于JavaScript的原型继承,因此会受到可变阴影的影响。

  2. 子作用域通常从其父作用域继承原型。该规则的一个例外是指令,该指令具有隔离的范围,因为它不典型地继承。

  3. 有一些特殊指令,创建一个新的子范围:ng-repeat,ng-switch,ng-view,ng-if,ng-controller,ng-include,等。

这意味着当您尝试将某些数据双向绑定到子作用域内的原语时(反之亦然),事情可能无法按预期进行。这是一个“轻松”破坏AngularJS的示例。

通过执行以下步骤可以轻松避免此问题:

  1. 有一个 ”。” 在您绑定一些数据时在HTML模板中

  2. 使用controllerAs语法,因为它促进了对“点状”对象的绑定的使用

  3. $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调用它们的频率可能比代码其他部分(参考)更高。