我在使用表单时遇到一些基本麻烦。这就是我所做的。
我从这里获取了这个很酷的指令:https : //github.com/TheSharpieOne/angular-input- match
看起来像这样:
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); }); } }; });
本质上,此指令监视其附加到模型值的元素,并将其与match属性中的模型值进行比较。
所以…例如,下面我们正在看两个密码是否匹配:
Password: <input ng-model="password" type="password" /> Confirm: <input ng-model="passwordConfirm" type="password" match="password" />
该指令似乎有效,因为它可以适当地设置ng-valid-match和ng-invalid-match。
但是,一旦将其设置为无效,passwordConfirm模型就不会再更新。我做了很多console.loggin,在指令中查看ngModel,这是两个密码匹配时的样子:
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
请注意,$ viewValue是正确的,但是$ modelValue被列为未定义,并且$ invalidModelValue仍然具有值。
这是html的样子,当两个密码都匹配时:
<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="">
我在某处缺少什么吗?我已经在圈子里跑了好几个小时了。
看起来使用$setValidity可能不是这里的方法。我发现这个问题提出了一个不同的解决方案,使用$ validators和$ validate(),这对我来说非常有用。新代码如下所示:
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; }; } }; });