Angularjs setValidity导致modelValue不更新
我的表格有一些基本的问题。这就是我所做的 我从这里找到了这个看起来很酷的指令: 看起来是这样的:Angularjs setValidity导致modelValue不更新,angularjs,validation,angularjs-directive,Angularjs,Validation,Angularjs Directive,我的表格有一些基本的问题。这就是我所做的 我从这里找到了这个看起来很酷的指令: 看起来是这样的: directive('match', function () { return { require: 'ngModel', restrict: 'A', scope: { match: '=' }, link: function(scope, elem, attrs, ngModel) { scope
directive('match', function () {
return {
require: 'ngModel',
restrict: 'A',
scope: {
match: '='
},
link: function(scope, elem, attrs, ngModel) {
scope.$watch(function() {
return (ngModel.$pristine && angular.isUndefined(ngModel.$modelValue)) || scope.match === ngModel.$viewValue;
}, function(currentValue, previousValue) {
ngModel.$setValidity('match', currentValue);
});
}
};
});
directive('match', function () {
return {
require: 'ngModel',
restrict: 'A',
scope: {
match: '='
},
link: function(scope, elem, attrs, ngModel) {
scope.$watch('match', function(pass){
ngModel.$validate();
});
ngModel.$validators.match = function(modelValue, viewValue){
var value = modelValue || viewValue;
var match = scope.match;
return value === match;
};
}
};
});
本质上,该指令监视它附加到的元素的模型值,并将其与match属性中的模型值进行比较
因此…例如,下面我们将观察两个密码是否匹配:
Password: <input ng-model="password" type="password" />
Confirm: <input ng-model="passwordConfirm" type="password" match="password" />
Constructor {$viewValue: "asdf", $modelValue: undefined, $validators: Object, $parsers: Array[0], $formatters: Array[0]…}
$$debounceViewValueCommit: function (trigger, revalidate) {
$$invalidModelValue: "asdf"
$$lastCommittedViewValue: "asdf"
$$runValidators: function (modelValue, viewValue) {
$$validityState: ValidityState
$$writeModelToScope: function () {
$commitViewValue: function (revalidate) {
$dirty: true
$error: Object
$formatters: Array[0]
$invalid: false
$isEmpty: function (value) {
$modelValue: undefined
$name: "passwordConfirmation"
$parsers: Array[0]
$pristine: false
$render: function () {
$rollbackViewValue: function () {
$setPristine: function () {
$setTouched: function () {
$setUntouched: function () {
$setValidity: function (validationErrorKey, isValid) {
$setViewValue: function (value, trigger, revalidate) {
$touched: true
$untouched: false
$valid: true
$validate: function () {
$validators: Object
$viewChangeListeners: Array[0]
$viewValue: "asdf"
__proto__: Object
<input type="password" class="form-control ng-isolate-scope ng-dirty ng-valid-required ng-valid ng-valid-match ng-touched" id="passwordConfirmation" name="passwordConfirmation" placeholder="Confirm your password" ng-model="passwordConfirmation" required="" match="password" style="">
请注意,$viewValue是正确的,但$modelValue列为未定义,$invalidModelValue仍有一个值
下面是两个密码匹配时html的外观:
Password: <input ng-model="password" type="password" />
Confirm: <input ng-model="passwordConfirm" type="password" match="password" />
Constructor {$viewValue: "asdf", $modelValue: undefined, $validators: Object, $parsers: Array[0], $formatters: Array[0]…}
$$debounceViewValueCommit: function (trigger, revalidate) {
$$invalidModelValue: "asdf"
$$lastCommittedViewValue: "asdf"
$$runValidators: function (modelValue, viewValue) {
$$validityState: ValidityState
$$writeModelToScope: function () {
$commitViewValue: function (revalidate) {
$dirty: true
$error: Object
$formatters: Array[0]
$invalid: false
$isEmpty: function (value) {
$modelValue: undefined
$name: "passwordConfirmation"
$parsers: Array[0]
$pristine: false
$render: function () {
$rollbackViewValue: function () {
$setPristine: function () {
$setTouched: function () {
$setUntouched: function () {
$setValidity: function (validationErrorKey, isValid) {
$setViewValue: function (value, trigger, revalidate) {
$touched: true
$untouched: false
$valid: true
$validate: function () {
$validators: Object
$viewChangeListeners: Array[0]
$viewValue: "asdf"
__proto__: Object
<input type="password" class="form-control ng-isolate-scope ng-dirty ng-valid-required ng-valid ng-valid-match ng-touched" id="passwordConfirmation" name="passwordConfirmation" placeholder="Confirm your password" ng-model="passwordConfirmation" required="" match="password" style="">
我是不是错过了什么?我已经在圈里跑了几个小时。可能与您正在使用
scope: {
match : "="
}
这将为您的指令创建一个独立的作用域,并且不会从您的ngModel所在的父作用域中删除
我建议尝试删除指令的作用域部分,改为从属性访问它
它将变成这样:
directive('match', function () {
return {
require: 'ngModel',
restrict: 'A',
link: function(scope, elem, attrs, ngModel) {
scope.match = attrs.match;
scope.$watch(function() {
return (ngModel.$pristine && angular.isUndefined(ngModel.$modelValue)) || scope.match === ngModel.$viewValue;
}, function(currentValue, previousValue) {
ngModel.$setValidity('match', currentValue);
});
}
};
});
在a中,根据字段的有效性更改了$modelValue
的填充方式。如果该字段无效,则$$modelValue
将设置为未定义
,并用该值填充一个新属性$$invalidModelValue
作为使用1.2.*和1.3.*的解决方案,我提出了以下建议:
.directive('match', function () {
return {
require: 'ngModel',
restrict: 'A',
scope: {
match: '='
},
link: function(scope, elem, attrs, ctrl) {
scope.$watch(function() {
modelValue = ctrl.$modelValue || ctrl.$$invalidModelValue;
return (ctrl.$pristine && angular.isUndefined(modelValue)) || scope.match === modelValue;
}, function(currentValue) {
ctrl.$setValidity('match', currentValue);
});
}
};
});
虽然此解决方案同时适用于这两个版本,但1.3.*具有新的
$validators
管道,这是新版本的推荐管道。看起来可能使用$setvalidation不是解决方案。我发现它提出了一个不同的解决方案,使用$validators和$validate(),这对我来说非常有用。新代码如下所示:
directive('match', function () {
return {
require: 'ngModel',
restrict: 'A',
scope: {
match: '='
},
link: function(scope, elem, attrs, ngModel) {
scope.$watch(function() {
return (ngModel.$pristine && angular.isUndefined(ngModel.$modelValue)) || scope.match === ngModel.$viewValue;
}, function(currentValue, previousValue) {
ngModel.$setValidity('match', currentValue);
});
}
};
});
directive('match', function () {
return {
require: 'ngModel',
restrict: 'A',
scope: {
match: '='
},
link: function(scope, elem, attrs, ngModel) {
scope.$watch('match', function(pass){
ngModel.$validate();
});
ngModel.$validators.match = function(modelValue, viewValue){
var value = modelValue || viewValue;
var match = scope.match;
return value === match;
};
}
};
});
只要值无效,模型将返回undefined,当它与条件匹配时,模型将更新为Right,但form元素将设置为valid,因此我希望模型值得到适当更新。设置
$modelValue
的方式发生了重大变化。如果模型无效,它会将值设置为$$invalidModelValue
建议您自己回答问题并接受答案,而不是在问题的末尾提供解决方案。建议将此作为答案,这对我也有帮助…这似乎不起作用,因为attrs.match不是“密码”的值,它实际上只是字符串“password”本身。当我将作用域声明保留在那里时,scope.match等于password的模型值,因此这似乎确实有效。您是否尝试过scope.$eval(attrs.match)?