我编写了一个验证指令multiple-pattern
,它带有几个验证正则表达式:
link: function (scope, elm, attr, ctrl) {
if (!ctrl) return;
let validators = [];
attr.$observe('multiplePattern', function (patterns) {
// doesn't get there after value change
var parsed = scope.$eval(patterns);
但我不明白为什么当控制器$observe
上的变量发生变化时未触发validationRegexps
回调(更改regexp
变量时会触发ng-repeat的回调):< / p>
$scope.regexp = '^\\S*$';
$scope.validationRegexps = {'nospaces': '^\\S*$', 'nofirstnumber': '^[A-Za-z]'};
setTimeout(function () {
$scope.$apply(function () {
$scope.regexp = '[^abc]';
$scope.validationRegexps = {'noabc': '[^abc]'};
})
}, 5000);
用法:
<div ng-pattern="regexp" multiple-pattern="validationRegexps"></div>
答案 0 :(得分:1)
$observe
与$watch
的工作方式相同。但这两者之间的差异是$watch
需要string
值或expression
&amp;评估每个摘要周期,其中$observe
采用interpolated
表达式{{validationRegexps}}
。
attr.$observe
仅在您使用attribute
内插内容{{}}
时才有效。
<强> HTML 强>
<div ng-pattern="regexp" multiple-pattern="{{validationRegexps}}"></div>
答案 1 :(得分:0)
我刚检查了源代码,似乎有ng-pattern
值的特殊处理,允许$observe
正确工作而不指定插值:
var ALIASED_ATTR = {
'ngMinlength': 'minlength',
'ngMaxlength': 'maxlength',
'ngMin': 'min',
'ngMax': 'max',
'ngPattern': 'pattern'
};
forEach(ALIASED_ATTR, function(htmlAttr, ngAttr) {
ngAttributeAliasDirectives[ngAttr] = function() {
return {
priority: 100,
link: function(scope, element, attr) {
//special case ngPattern when a literal regular expression value
//is used as the expression (this way we don't have to watch anything).
if (ngAttr === "ngPattern" && attr.ngPattern.charAt(0) == "/") {
var match = attr.ngPattern.match(REGEX_STRING_REGEXP);
if (match) {
attr.$set("ngPattern", new RegExp(match[1], match[2]));
return;
}
}
scope.$watch(attr[ngAttr], function ngAttrAliasWatchAction(value) {
// here the value is already interpolated
attr.$set(ngAttr, value);
});
}
};
};
});
与$observe
:
$observe: function(key, fn) {
var attrs = this,
$$observers = (attrs.$$observers || (attrs.$$observers = createMap())),
listeners = ($$observers[key] || ($$observers[key] = []));
listeners.push(fn);
$rootScope.$evalAsync(function() {
if (!listeners.$$inter && attrs.hasOwnProperty(key) && !isUndefined(attrs[key])) {
// not interpolated value is passed down here
fn(attrs[key]);
}
});
return function() {
arrayRemove(listeners, fn);
};
}