我有以下标记:
<div ng-controller="DataController as vm">
<div ng-repeat="name in vm.users track by $index">
{{name}}
</div>
<form name="form" validation="vm.errors">
<input validator ng-model="vm.name" name="vm.name" placeholder="name" type="text" />
<a href="#" ng-click="vm.add(vm.name)">Add</a>
</form>
</div>
我有以下控制器:
function DataController($scope) {
var vm = this;
vm.name = "Mary";
vm.users = ["Alice", "Peter"];
vm.errors = 1;
vm.add = function(name) {
vm.errors++;
vm.users.push(name);
}
}
每次添加用户时,我都会增加错误值。
我需要在指令中观察这个变量,所以我有:
app.directive("validation", validation);
function validation() {
var validation = {
controller: ["$scope", controller],
restrict: "A",
scope: {
validation: "="
}
};
return validation;
function controller($scope) {
this.errors = $scope.validation;
}
}
app.directive("validator", validator);
function validator() {
var validator = {
link: link,
replace: false,
require: "^validation",
restrict: "A"
};
return validator;
function link(scope, element, attributes, controller) {
scope.$watch(function() {
return controller.errors;
}, function () {
console.log(controller.errors);
});
}
console.log显示初始值但不显示新值:
https://jsfiddle.net/qb8o006h/2/
如果我将vm.errors更改为数组,添加值,并观察其长度,那么它工作正常: https://jsfiddle.net/nprx63qa/2/
为什么我的第一个例子不起作用?
答案 0 :(得分:1)
在validation
指令controller
中的两个示例中,您为errors
属性分配了对$scope.validation
值的引用。
在第一个示例中,值为数字,因此不可变 - 1
- 无法修改参考值。 vm.add
修改控制器实例的属性值。然后,更改将传播到validation
指令$scope.validation
,但不传播到validation
指令控制器实例$errors
属性。
在第二个示例中,值是一个数组,因此可变 - []
- 可以修改参考值。 vm.add
不修改控制器实例的属性值。因此,validation
指令控制器实例errors
属性值是完全相同的Array
实例 - 因此它会length
更改。
使用不可变值的一种方法(如第一个示例中所示)是$watch
控制器函数,如this example中所示:
function link(scope, element, attributes, controller) {
scope.$watch(controller.errors, function (newValue) {
console.log(newValue);
});
}
controller.errors
的定义如下:
function controller($scope) {
this.errors = function(){ return $scope.validation; };
}
您可以找到以下有用的答案:
答案 1 :(得分:1)
我更新你的代码,你可以访问更新的属性scope.vm.errors,如果你调试代码,你会看到属性controller.errors没有更新(每次摘要后所有的手表都被调用)重新评估他们)。如果从范围访问属性错误,可以添加$ scope。$ watch并使其工作。但是我不建议在指令中使用$ scope。$ watch。但那取决于你:
var app = angular.module('app', []);
app.controller("DataController", DataController);
function DataController($scope) {
var vm = this;
vm.name = "Mary";
vm.users = ["Alice", "Peter"];
vm.errors = 1;
vm.add = function(name) {
vm.errors++;
vm.users.push(name);
}
}
app.directive("validation", validation);
function validation() {
var validation = {
controller: ["$scope", controller],
restrict: "A",
scope: {
validation: "="
}
};
return validation;
function controller($scope) {
this.errors = $scope.validation;
}
}
app.directive("validator", validator);
function validator() {
var validator = {
link: link,
replace: false,
require: "^validation",
restrict: "A"
};
return validator;
function link(scope, element, attributes, controller) {
scope.$watch(function() {
return scope.vm.errors
}, function () {
console.log(scope.vm.errors);
});
}
}