TLDR:为什么angular的ngMinlength接收带有插值的$ observe更新,但是我的自定义验证指令没有?
我正在研究Angular 1.3中的自定义验证指令,并注意到一些似乎不一致的东西。 angular中的指令似乎从attr。$ observe获得插值更新,但我创建的指令的行为方式不同。
我可以使用$ watch来修复它,或绑定插值,但与现有的验证指令不一致。有什么区别,我如何让我的自定义指令与内置验证指令类似?
Angular的指令
var minlengthDirective = function() {
return {
restrict: 'A',
require: '?ngModel',
link: function(scope, elm, attr, ctrl) {
if (!ctrl) return;
var minlength = 0;
attr.$observe('minlength', function(value) {
minlength = int(value) || 0;
ctrl.$validate();
});
ctrl.$validators.minlength = function(modelValue, viewValue) {
return ctrl.$isEmpty(viewValue) || viewValue.length >= minlength;
};
}
};
};
我的指示
function observeMinLength($log){
return {
restrict: 'A',
require: '?ngModel',
link: function (scope, elm, attr, ctrl) {
if (!ctrl) return;
var min;
//Problem 1: observered value is not interpolated
//Problem 2: observe is only fired one time
attr.$observe('observeMinlength', function (value) {
$log.debug('observed value: ' + value);
min = parseInt(value, 10) || 0;
ctrl.$validate();
});
ctrl.$validators.mymin = function (modelValue, viewValue) {
var len = 0;
if (viewValue){
len = viewValue.length;
}
return ctrl.$isEmpty(viewValue) || viewValue.length >= min;
};
}
};
}
答案 0 :(得分:0)
请注意,ngMinlength指令是$ observe“minlength”属性,而不是“ngMinlength”属性。我认为问题在于Angular的输入指令是基于内插值设置minlength属性...所以当ngMinlength属性的值不随其值的变化而变化时,minlength属性就是可观察的原因。在您的指令中,属性observeMinLength不会更改,但传入的scope属性的值会更改。
如果您查看角度源代码:https://github.com/angular/angular.js/blob/13b7bf0bb5262400a06de6419312fe3010f79cb2/src/ng/directive/attrs.js#L379,您可以看到angular正在观察范围变量并为ALIASED_ATTR集合中的所有属性设置属性变量。该集合定义为
var ALIASED_ATTR = {
'ngMinlength': 'minlength',
'ngMaxlength': 'maxlength',
'ngMin': 'min',
'ngMax': 'max',
'ngPattern': 'pattern'
};
https://github.com/angular/angular.js/blob/2e0e77ee80236a841085a599c800bd2c9695475e/src/jqLite.js#L575 中的
简而言之,Angular对其自己的基于属性的验证指令进行了特殊处理。因此,您需要观察范围属性,而不是观察属性。