我正在编写一个AngularJS指令,并希望将ng-model值绑定到控制器中的对象数组。当数组中的任何内容发生更改时,我希望在指令链接中使用$ render。实际上,只有在更改对数组的引用时才会触发$ render。这是为什么这是ngModelController的预期行为?
下面的代码演示了这种行为以及这个小提琴:http://jsfiddle.net/HandyManDan/RCctF/
<div ng-app="tryApp">
<div ng-controller="MyCtrl">
<div> Bound in controller: {{modelVals[0].val}}</div>
<div> Bound in directive: <span my-dir="" ng-model="modelVals"></span></div>
<button ng-click="lftBtn()">Mod deep</button>
<button ng-click="rtBtn()">Mod ref</button>
</div>
</div>
myApp.controller('MyCtrl', function($scope) {
$scope.modelVals = [{val:'val init'}];
$scope.lftBtn = function() {
$scope.modelVals[0].val = 'val change deep';
};
$scope.rtBtn = function() {
$scope.modelVals = [{val:'val change ref'}];
};
});
myApp.directive('myDir', function() {
return {
restrict: 'A',
priority: 1,
require: 'ngModel',
link: function(scope, element, attr, ngModel) {
ngModel.$render = function() {
element.find('*').remove();
var el = angular.element("<span>" + ngModel.$modelValue[0].val + "</span>)");
element.append(el);
};
}
};
});
答案 0 :(得分:1)
尝试重写您的指令,如下所示:
myApp.directive('myDir', function() {
return {
restrict: 'A',
priority: 1,
scope: {
'ngModel': '='
},
template: "<span>{{ngModel[0].val}}</span>"
};
});
答案 1 :(得分:1)
在深入角度源之后,我确定这是预期的行为。它在这里有一些记录http://docs.angularjs.org/api/ng/directive/select
注意:ngModel按引用进行比较,而不是值。这很重要 绑定到一个对象数组。
ngModelController为绑定到ng-model的值设置观察程序。随后发射的手表会调用$ render。观察者采用这种形式
$ watch(watchExpression,[listener]);
这种形式的手表仅限于参考更改。
要实现此功能,当指令在对象值更改时获取事件时,需要使用以下形式在ng-model绑定值上设置自己的监视:
$ watch(watchExpression,[listener],[objectEquality]);
将objectEquality设置为true表示对象值比较。
不幸的是,使用$ watch而不是$ render会绕过ngModelController的格式化程序/验证程序链。