我写了一个match-model
Angular指令,当用户在我的应用程序中注册时,我用它来进行密码/密码重复处理。密码重复字段具有此特定属性,可根据原始密码字段验证此字段。
我的指令有scope.$watch
用于优化目的,因为每次我验证我的重复密码范围属性时我都不必读取相关的范围属性值,但我只是使用缓存的值,当相关的范围属性值发生更改时,该值会发生变化(原始密码)。
这是我的指示:
.directive("matchModel", ["$timeout", function ($timeout) {
return {
require: "ngModel",
link: function (scope, element, attributes, ngModelController) {
var valueCache = null;
// watch "match-model" model property value
scope.$watch(attributes["matchModel"], function (newValue, oldValue) {
valueCache = newValue;
/*
scope.$apply(); // error $digest in progress
$timeout(function () { scope.$digest(); }); // no error, not working
$timeout(function () { scope.$apply(); }); // no error, not working
*/
});
// add model validation parser
ngModelController.$parsers.unshift(function (value) {
ngModelController.$setValidity("match", value === valueCache);
return value === valueCache ? value : undefined;
});
}
};
}]);
我的表单由两个字段组成(与此问题相关):
<input type="password" name="password" id="password" placeholder="password"
class="validate" autocomplete="off"
required
ng-minlength="6"
ng-model="data.password" />
<input type="password" name="passwordRepeat" id="passwordRepeat" placeholder="repeat password"
class="validate" autocomplete="off"
required
ng-model="data.passwordRepeat"
match-model="data.password" />
1和2按预期工作,但3没有。这就是我想添加scope.$digest
以将范围模型更改传播到其他字段的原因。并且scope.$watch
是正确的时刻,因为它在特定范围模型属性更改时执行。
scope.$digest
(或scope.$apply
)似乎不验证模型。验证似乎没有与它一起执行。
那么我应该如何做scope.$validate
甚至更好element.$validate
之类的事情,这样它才能验证我的特定字段而不是整个模型(导致UI中的表单无效)。
答案 0 :(得分:3)
我会通过明确验证$watch
:
的 PLUNKER 强>
app.directive("matchModel", [
function () {
return {
require: "ngModel",
link: function (scope, element, attributes, ngModelController) {
var valueCache = null;
scope.$watch(attributes["matchModel"], function (newValue, oldValue) {
valueCache = newValue;
validate(ngModelController.$viewValue);
});
var validate = function (value) {
ngModelController.$setValidity("match", value === valueCache);
return value === valueCache ? value : undefined;
};
ngModelController.$parsers.unshift(validate);
}
};
}]);
答案 1 :(得分:1)
我会这样做,只有一个地方检查它们是否相等:
app.directive("matchModel", function () {
return {
require: "ngModel",
link: function (scope, element, attributes, ngModelController) {
scope.$watch(function(){
return scope.$eval(attributes["matchModel"]) == ngModelController.$viewValue; //only 1 place to check if they are equal
}, function (newValue) {
ngModelController.$setValidity("match", newValue);
});
}
};
});