AngularJS:如果element具有ngModel且具有本地范围的指令,则双向数据绑定将失败

Ato*_*mix 13 angularjs

问题在这里显示:http: //jsfiddle.net/ews7S/

<input type="text" ng-model="testModel" dir="123">
Run Code Online (Sandbox Code Playgroud)

当元素绑定到控制器作用域中的模型并且还将指令添加到具有其自己的本地作用域的元素时,对模型的更改仅在指令作用域中更改.

Mar*_*cok 17

另一种解决方案是将对象用于模型,而不是原语.然后新的指令范围将继承(原型)对象的引用,而不是原始值的副本:

$scope.model = { testProp: "444" };

<input type="text" ng-model="model.testProp" dir="123">
<input type="text" ng-model="model.testProp">

document.getElementById("out").innerHTML = scope.model.testProp;
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/mrajcok/awfU5/

使用诸如$ scope.testModel之类的原语,指令范围的testModel属性获取父范围的testModel值的副本.对一个的更改不会影响另一个.

对于一个对象,例如$ scope.model,父作用域和指令作用域都引用了相同的(一个)对象.两者中的更改都会影响同一对象.

另一个(脆弱的)解决方案是使用未记录的 $ parent属性(对问题小提琴进行这些更改):

<input type="text" ng-model="$parent.testModel" dir="123">

document.getElementById("out").innerHTML = scope.$parent.testModel;
Run Code Online (Sandbox Code Playgroud)

请注意,使用$parent是一个脆弱的解决方案,因为使用$parent取决于DOM结构.例如,如果在父和子(现在是孙子)之间添加了另一个控制器(由您明确地或由另一个Angular指令隐式地添加),我们将需要使用$parent.$parent.testModel.


Ato*_*mix 6

解决方案是将此添加到指令:

scope: {testModel: '=ngModel'},
Run Code Online (Sandbox Code Playgroud)

见这里:http: //jsfiddle.net/ews7S/1/

为什么这样做是因为'='设置了本地范围属性和父范围属性之间的双向绑定(请参阅指令定义对象下的文档:http://docs.angularjs.org/guide/directive).

  • [ngModel](http://docs.angularjs.org/api/ng.directive:ngModel)比其他更简单的属性有更多的责任.因此,你也会遇到[NgModelController](http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController)的问题.当指令将链接到ngModel.$ viewValue/$ modelValue将没有你需要的. (2认同)