指令添加ng-pattern属性 [英] Directive to add ng-pattern attribute
问题描述
我正在尝试创建一个指令,该指令将自己替换为ng-pattern属性.该属性将应用于输入元素,但是此后该元素基本上变得不可用.我不能再在文本框中输入字符.
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.
这是pl人 http://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: true
,input
指令被编译了两次,并且添加了两组变更侦听器,这使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
,因此input指令不会将validateRegex
解析器添加到其解析器列表中.但是,第二次编译(通过您的$compile(iElement, scope)
)看到了ng-pattern
和
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.
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
,其中返回 undefined
(因为永远不要将模型设置为无效值).这是ngModel
指令中的关键-因为3
的先前$viewValue
和undefined
的新value
是将输入更新为空.因此,当您在输入框中键入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+
,否则很可能是其他指令).这很棒,因为您想要输入指令要考虑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屋!