我创建了一个简单的指令:
var app = angular.module('plunker', []);
function Data(n) {
this.n = n;
}
app.controller('MainCtrl', function($scope) {
$scope.data = [
new Data(1),
new Data(2),
new Data(3)
];
$scope.addNew = function() {
for (var i = 0; i < $scope.data.length; i += 1) {
$scope.data[i].n *= 10;
}
$scope.data.push(new Data(1));
}
});
app.directive('data', function() {
return {
require: 'ngModel',
template: '<div><span>n using scope: {{n}}</span><br><span>n using model: {{model.n}}</span></div>',
restrict: 'E',
link: postLink,
scope: {},
};
function postLink(scope, element, attrs, ngModelController) {
ngModelController.$render = function() {
var $viewValue = ngModelController.$viewValue;
scope.n = $viewValue.n;
scope.model = $viewValue;
};
}
});
Plunker链接here。
几次致电addNew()
后,我得到输出:
n using scope: 1
n using model: 1000
n using scope: 2
n using model: 2000
n using scope: 3
n using model: 3000
n using scope: 1
n using model: 100
n using scope: 1
n using model: 10
n using scope: 1
n using model: 1
我理解为什么scope.n
值未更新(正如ngModelController的文档中明确说明的那样,但我想知道为什么scope.model
值会更新?
答案 0 :(得分:1)
如果您使用console.log scope.model
和scope.n
,则会收到以下信息:
scope.model: Data {n: 1, $$hashKey: "object:21"}
scope.n: 1
我相信你看到的行为是因为ng-repeat:angular生成并附加一个$$ hashkey到对象,angular用来跟踪更新。
文档说这是关于$ ngModelController的$ render方法:
由于ng-model没有深度监视,因此只有在调用时才会调用$ render() $ modelValue和$ viewValue的值实际上是不同的 他们以前的价值。如果$ modelValue或$ viewValue是对象(相反 如果你,那么$ render()将不会被调用 只更改对象的属性。
所以看起来$ render被调用scope.model,但不是scope.n,但我不相信它实际上是。我认为它正在更新,因为$$ hashkey与对象一起附加到scope.model。因为使用scope.n你没有获得哈希键,所以它不会更新。当angular执行$ digest时,它会看到$$ hashkey并尝试更新该绑定。
如果您取出$$ hashkeys,它将不再更新。我们可以通过在将$ viewValue附加到scope.model之前转换$ hashVal来剥离$$ hashkey:
scope.model = angular.fromJson(angular.toJson($viewValue));
现在,如果你使用console.log(scope.model),你会得到:
Object {n: 3}
不再使用$$ hashkey,并且视图的行为与您认为的方式相同 - $ render不会被调用。