与范围。$腕表角指令迫使其他领域的验证 [英] Angular directive with scope.$watch to force validation of other fields
问题描述
我已经写了匹配模型
当用户在我的申请注册,我使用的密码/密码,重复的过程角指令。密码重复场有验证这一方面对原来的密码领域这种特殊属性。
我的指令有范围。$看
优化的目的,因为我不必每次验证我重复密码scope属性,但我宁愿时间来阅读相关范围属性值只是使用的时候改变范围相关的属性值更改(初始密码)的缓存值
这是我的指令:
.directive(matchModel,[$超时功能($超时){
返回{
要求:ngModel
链接:功能(范围,元素,属性,ngModelController){ VAR valueCache = NULL; //看匹配模型模型属性值
范围。$表(属性[matchModel],功能(为newValue,属性oldValue){
valueCache =为newValue;
/ *
。范围$适用(); //错误$进行消化
$超时(函数(){$范围摘要();}); //没有错误,不工作
$超时(函数(){$范围适用于();}); //没有错误,不工作
* /
}); //添加模型验证解析器
ngModelController。$ parsers.unshift(函数(值){
ngModelController $ setValidity(匹配,值=== valueCache)。
返回值=== valueCache?值:未定义;
});
}
};
}]);
我的表单包含两个字段(即是相关的这个问题)的:
<输入类型=密码NAME =密码ID =密码占位符=密码
类=验证自动完成=关闭
需要
NG-= MINLENGTH6
NG-模式=data.password/>
<输入类型=密码NAME =passwordRepeatID =passwordRepeat占位符=重复密码
类=验证自动完成=关闭
需要
NG-模式=data.passwordRepeat
匹配模型=data.password/>
要求
- 当用户输入一个密码,字段时,输入的字符足以成为有效的 - 在这6个字符 上述情况
- 当用户进入第二个密码,字段应该当数据匹配的第一个口令生效
- 如果用户返回到第一场和改变原始密码,第二场应该废止
目前它是如何工作的
1和2的工作不如预期,但3没有。这就是为什么我想补充范围。$摘要
传播到其他领域范围模式的变化。和范围。$手表
是正确的时刻,因为它执行时特定范围内的模型属性的更改。
似乎范围。$摘要
(或范围。$适用
为此事)不验证模型。验证似乎并没有与它一起执行
问题
所以,我应该怎么做类似范围。$验证
甚至更好元素。$验证
所以它会只是验证我的特定领域,而不是整个模型(导致无效的形式在UI)。
我要通过明确验证$ viewValue里面做了 $观看
:
<大骨节病> PLUNKER 大骨节病>
app.directive(matchModel,[
功能(){
返回{
要求:ngModel
链接:功能(范围,元素,属性,ngModelController){ VAR valueCache = NULL; 范围。$表(属性[matchModel],功能(为newValue,属性oldValue){
valueCache =为newValue;
验证(ngModelController $ viewValue);
}); VAR验证=功能(值){
ngModelController $ setValidity(匹配,值=== valueCache)。
返回值=== valueCache?值:未定义;
}; ngModelController $ parsers.unshift(验证)。
}
};
}]);
I've written a match-model
Angular directive that I use for password/password-repeat process when users register in my application. Password repeat field has this particular attribute that validates this field against original password field.
My directive has scope.$watch
for optimization purposes because I don't have to read related scope property value each time I validate my repeat password scope property but I rather just use cached value which changes when related scope property value changes (original password).
This is my directive:
.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;
});
}
};
}]);
My form consists of two fields (that are relevant for this question):
<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" />
Requirements
- When user enters first password, field becomes valid when enough characters are entered - in above case that's 6 characters
- when user enters second password, field should become valid when data matches first password
- if user returns to first field and changes original password, second field should invalidate
How it currently works
1 and 2 work as expected, but 3 doesn't. That's why I wanted to add scope.$digest
to propagate scope model changes to other fields. And scope.$watch
is the right moment because it executes when that particular scope model property changes.
It seems that scope.$digest
(or scope.$apply
for that matter) doesn't validate model. Validation doesn't seem to be executed along with it.
Question
So how should I do something like scope.$validate
or even better element.$validate
so it would only validate my particular field instead of the whole model (resulting in invalid form in the UI).
I would do it by explicitly validating the $viewValue inside the $watch
:
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);
}
};
}]);
这篇关于与范围。$腕表角指令迫使其他领域的验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!