添加 ng-pattern 属性的指令 [英] Directive to add ng-pattern attribute

查看:26
本文介绍了添加 ng-pattern 属性的指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个指令,该指令将用 ng-pattern 属性替换自身.该属性被应用于 input 元素,但此后该元素基本上变得不可用.我无法再在文本框中输入字符.

I am trying to create a directive that will replace itself with the ng-pattern attribute. The attribute gets applied to the input element but the element basically becomes unusable after that. I can no longer enter characters into the text box.

这里是plunkrhttp://plnkr.co/edit/F6ZQYzxd8Y04Kz8xQmnZ?p=preview

我想我一定是在添加属性后错误地编译了元素.

I think I must be compiling the element incorrectly after the attribute is added.

app.directive('passwordPattern', ['$compile', function($compile){
    return{
    compile: function (element, attr){

        element.removeAttr('password-pattern');
        element.attr('ng-pattern', '/^[\\w\\S]{6,12}$/');

        return {
            pre: function preLink(scope, iElement, iAttrs, controller) {  },
            post: function postLink(scope, iElement, iAttrs, controller) {
                $compile(iElement)(scope);
            }
        };
    }
};
}]);

任何关于解决方案的想法或文本框变得不可用的原因都将受到极大的赞赏.谢谢.

Any thoughts on a solution or why the textbox becomes unusable would be greatly apprecitated. Thanks.

推荐答案

除了priority: 1000,还需要添加terminal: true.

问题是没有 terminal: trueinput 指令会被编译两次,并且添加了 2 组更改侦听器,这会稍微抛出 ngModel 指令逻辑.

The issue is that without terminal: true, the input directive gets compiled twice, and 2 sets of change listeners are getting added, which throws the ngModel directive logic off a bit.

Angular 执行的第一次编译没有看到 ng-pattern,因此输入指令不会将 validateRegex 解析器添加到其解析器列表中.但是,第二次编译(通过您的 $compile(iElement, scope))看到 ng-pattern 并且 does 添加 validateRegex 解析器.

The first compile Angular performs doesn't see the ng-pattern, so the input directive doesn't add the validateRegex parser to its list of parsers. However, the second compile (via your $compile(iElement, scope)) sees the ng-pattern and does add the validateRegex parser.

当您在输入框中输入 3 时,调用第一个更改侦听器 并看到数字 3.由于没有应用 ng-pattern(这会添加 validateRegex $parser),所以不存在 $parsers 并且模型更新为3 立即.

When you type, say 3, into the input box, the first change listener is called and sees the number 3. Since no ng-pattern was applied (which would've added the validateRegex $parser), no $parsers exist and the model is updated with 3 immediately.

但是,当调用第二个更改侦听器时,它会看到 ng-pattern 并调用 validateRegex,其中 调用 ngModel.$setValidity('pattern', false)返回 undefined(因为模型永远不应该设置为无效值).这是踢球者 - 在 ngModel 指令内,因为 3 的前一个 $viewValue 新的 value>undefined同步,Angular 调用输入指令的$render 函数,该函数更新输入为空.因此,当您在输入框中键入 3(或任何内容)时,它会立即被删除并且看起来已损坏.

However, when the second change listener is called, it sees the ng-pattern and calls validateRegex, which calls ngModel.$setValidity('pattern', false) and returns undefined (because the model should never be set to an invalid value). Here's the kicker - inside the ngModel directive, since the previous $viewValue of 3 and new value of undefined are out of sync, Angular calls the input directive's $render function, which updates the input to be empty. Thus when you type 3 (or anything) into the input box, it's immediately removed and appears to be broken.

priority(如 1000)和 terminal: true 将阻止输入指令(以及很可能其他指令,除非你有一个这是 priority: 1001+) 从第一次编译开始.这很棒,因为您希望 input 指令考虑 ng-pattern - 而不是没有它.您不希望将多组更改侦听器添加到同一元素,否则可能(并且将会)导致奇怪的副作用.

A high priority (like 1000) and terminal: true will prevent the input directive (and most likely other directives unless you have one that's priority: 1001+) from being compiled the first time. This is great because you want the input directive to take into account ng-pattern - not without it in place. You don't want multiple sets of change listeners added to the same element or it may (and will) cause strange side-effects.

这篇关于添加 ng-pattern 属性的指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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