我正在尝试创建一个指令,它将自身替换为 ng-pattern 属性。该属性被应用于输入元素,但此后该元素基本上变得不可用。我无法再在文本框中输入字符。
这是plunkr http://plnkr.co/edit/F6ZQYzxd8Y04Kz8xQmnZ?p=preview
我想我一定是在添加属性后错误地编译了元素。
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);
}
};
}
};
}]);
如有任何关于解决方案的想法或文本框无法使用的原因,我们将不胜感激。谢谢。
最佳答案
除了priority: 1000
,还需要添加terminal: true
。
问题是没有 terminal: true
,input
指令被编译了两次,并且添加了 2 组更改监听器,这会稍微偏离 ngModel
指令逻辑。
Angular 执行的第一次编译没有看到 ng-pattern
,因此输入指令不会将 validateRegex
解析器添加到它的解析器列表中。但是,第二次编译(通过您的 $compile(iElement, scope)
)看到了 ng-pattern
并且确实 add validateRegex
解析器。
当您在输入框中键入3
时,first change listener is called并看到数字 3
。由于没有应用 ng-pattern
(这会添加 validateRegex $parser
),因此不存在 $parsers
并且模型更新为3
立即。
但是,当调用第二个更改监听器时,它会看到 ng-pattern
并调用 validateRegex
,这 calls ngModel.$setValidity('pattern', false)
和 returns undefined
(因为永远不应将模型设置为无效值)。这是踢球者 - 在 ngModel
指令内,因为 3
的先前 $viewValue
和 的新
是 out of sync , Angular 调用输入指令的 value
>undefined$render
函数,updates the input是空的。因此,当您在输入框中键入 3
(或任何内容)时,它会立即被删除并且看起来已损坏。
高 priority
(如 1000
)和 terminal: true
将阻止输入指令(很可能还有其他指令,除非你有一个那是 priority: 1001+
) 从第一次编译开始。这很棒,因为您希望输入指令考虑 ng-pattern - 不是没有它。您不希望将多组更改监听器添加到同一元素,否则它可能(并且将会)导致奇怪的副作用。
关于angularjs - 添加 ng-pattern 属性的指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22823545/