带有 scope.$watch 的 Angular 指令强制验证其他字段 [英] Angular directive with scope.$watch to force validation of other fields

查看:22
本文介绍了带有 scope.$watch 的 Angular 指令强制验证其他字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了一个 match-model Angular 指令,当用户在我的应用程序中注册时,我将其用于密码/密码重复过程.密码重复字段具有此特定属性,可根据原始密码字段验证此字段.

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.

我的指令有 scope.$watch 用于优化目的,因为我不必每次验证重复密码范围属性时都读取相关的范围属性值,而是只使用更改的缓存值当相关范围属性值更改时(原始密码).

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).

这是我的指令:

.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" />

要求

  1. 当用户输入第一个密码时,当输入足够的字符时,字段才有效 - 在上述情况下为 6 个字符
  2. 当用户输入第二个密码时,字段应在数据与第一个密码匹配时有效
  3. 如果用户返回第一个字段并更改原始密码,则第二个字段应失效

目前的工作方式

1 和 2 按预期工作,但 3 没有.这就是为什么我想添加 scope.$digest 以将范围模型更改传播到其他字段.而 scope.$watch 是正确的时机,因为它会在特定范围模型属性更改时执行.

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.

似乎 scope.$digest (或 scope.$apply 就此而言)不验证模型.验证似乎没有随之执行.

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.

那么我应该如何做像 scope.$validate 甚至更好的 element.$validate 这样的事情,这样它只会验证我的特定字段而不是整个模型(结果在 UI 中以无效形式显示).

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).

推荐答案

我会通过显式验证 $watch 中的 $viewValue 来实现:

I would do it by explicitly validating the $viewValue inside the $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);
      }
    };
}]);

这篇关于带有 scope.$watch 的 Angular 指令强制验证其他字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆