自定义 notPattern 指令,如 ngPattern,但检查 RegExp 是否不匹配
Custom notPattern directive like ngPattern, but checking whether a RegExp does not match
我正在尝试编写类似于 ngPattern 的自定义 AngularJS 指令,但如果 RegExp 不 匹配,此指令将无法通过验证。
根据 ngPattern 指令的 the source,我想出了:
.directive("notPattern", function () {
return {
restrict: "A",
require: "?ngModel",
link: function (scope, elem, attr, ctrl) {
if (!ctrl) return;
var regExp, notPatternExp = attr.notPattern;
attr.$observe("notPattern", function (regex) {
if (angular.isString(regex) && regex.length > 0) {
regex = new RegExp("^" + regex + "$");
}
if (regex && !regex.test) {
var elemClone = angular.element(elem).clone();
var elemHtml = angular.element("<div>").append(elemClone).html();
throw new Error("Expected " + notPatternExp + " to be a RegExp but was " + regex + ". Element: " + elemHtml);
}
regExp = regex || undefined;
ctrl.$validate();
});
ctrl.$validators.notpattern = function (value) {
return ctrl.$isEmpty(value) || angular.isUndefined(regExp) || !regExp.test(value);
};
}
};
})
当我在属性中指定正则表达式源时这有效,但我想允许直接使用 RegExp
对象,如 ngPattern。
问题是没有计算表达式。
这是一个 JSFiddle 示例:
http://jsfiddle.net/8Lk3pqep/1/
在此示例中,在文本字段中输入 "abc" 以外的任何内容都将显示 "Invalid per 'pattern'!"。我希望在输入 "abc" 时看到 "Invalid per 'notpattern'!",但这仅在我输入 "testRegExp" 时出现,这表明未评估属性值。
我做错了什么?
我知道 notPattern 可以通过 ngPattern 通过类似的方式完成:
$scope.testRegExp = {
test: function (value) {
return !/^abc$/.test(value);
}
};
..但我想知道为什么自定义指令不计算表达式。
事实证明,ngPattern 是 "aliased input attr" 的 Angular 中的一个特例,这意味着手表被设置为通过更高优先级指令评估表达式。 watch 监听器函数只是每次将属性设置为评估结果:
https://github.com/angular/angular.js/blob/bfcf9946e16d21b55dde50d4d21c71c898b10215/src/ng/directive/attrs.js#L377
要修复 notPattern 指令,而不是观察 notPattern 属性,设置 notPattern 表达式的监视以反映 ngPattern 属性的内置设置:
.directive("notPattern", function () {
return {
restrict: "A",
require: "?ngModel",
link: function (scope, elem, attr, ctrl) {
if (!ctrl) return;
var regExp, notPatternExp = attr.notPattern;
scope.$watch(notPatternExp, function (regex) {
if (angular.isString(regex) && regex.length > 0) {
regex = new RegExp("^" + regex + "$");
}
if (regex && !regex.test) {
var elemClone = angular.element(elem).clone();
var elemHtml = angular.element("<div>").append(elemClone).html();
throw new Error("Expected " + notPatternExp + " to be a RegExp but was " + regex + ". Element: " + elemHtml);
}
regExp = regex || undefined;
ctrl.$validate();
});
ctrl.$validators.notpattern = function (value) {
return ctrl.$isEmpty(value) || angular.isUndefined(regExp) || !regExp.test(value);
};
}
};
})
这是一个更新的 JSFiddle:
http://jsfiddle.net/8Lk3pqep/2/
我正在尝试编写类似于 ngPattern 的自定义 AngularJS 指令,但如果 RegExp 不 匹配,此指令将无法通过验证。
根据 ngPattern 指令的 the source,我想出了:
.directive("notPattern", function () {
return {
restrict: "A",
require: "?ngModel",
link: function (scope, elem, attr, ctrl) {
if (!ctrl) return;
var regExp, notPatternExp = attr.notPattern;
attr.$observe("notPattern", function (regex) {
if (angular.isString(regex) && regex.length > 0) {
regex = new RegExp("^" + regex + "$");
}
if (regex && !regex.test) {
var elemClone = angular.element(elem).clone();
var elemHtml = angular.element("<div>").append(elemClone).html();
throw new Error("Expected " + notPatternExp + " to be a RegExp but was " + regex + ". Element: " + elemHtml);
}
regExp = regex || undefined;
ctrl.$validate();
});
ctrl.$validators.notpattern = function (value) {
return ctrl.$isEmpty(value) || angular.isUndefined(regExp) || !regExp.test(value);
};
}
};
})
当我在属性中指定正则表达式源时这有效,但我想允许直接使用 RegExp
对象,如 ngPattern。
问题是没有计算表达式。
这是一个 JSFiddle 示例:
http://jsfiddle.net/8Lk3pqep/1/
在此示例中,在文本字段中输入 "abc" 以外的任何内容都将显示 "Invalid per 'pattern'!"。我希望在输入 "abc" 时看到 "Invalid per 'notpattern'!",但这仅在我输入 "testRegExp" 时出现,这表明未评估属性值。
我做错了什么?
我知道 notPattern 可以通过 ngPattern 通过类似的方式完成:
$scope.testRegExp = {
test: function (value) {
return !/^abc$/.test(value);
}
};
..但我想知道为什么自定义指令不计算表达式。
事实证明,ngPattern 是 "aliased input attr" 的 Angular 中的一个特例,这意味着手表被设置为通过更高优先级指令评估表达式。 watch 监听器函数只是每次将属性设置为评估结果:
https://github.com/angular/angular.js/blob/bfcf9946e16d21b55dde50d4d21c71c898b10215/src/ng/directive/attrs.js#L377
要修复 notPattern 指令,而不是观察 notPattern 属性,设置 notPattern 表达式的监视以反映 ngPattern 属性的内置设置:
.directive("notPattern", function () {
return {
restrict: "A",
require: "?ngModel",
link: function (scope, elem, attr, ctrl) {
if (!ctrl) return;
var regExp, notPatternExp = attr.notPattern;
scope.$watch(notPatternExp, function (regex) {
if (angular.isString(regex) && regex.length > 0) {
regex = new RegExp("^" + regex + "$");
}
if (regex && !regex.test) {
var elemClone = angular.element(elem).clone();
var elemHtml = angular.element("<div>").append(elemClone).html();
throw new Error("Expected " + notPatternExp + " to be a RegExp but was " + regex + ". Element: " + elemHtml);
}
regExp = regex || undefined;
ctrl.$validate();
});
ctrl.$validators.notpattern = function (value) {
return ctrl.$isEmpty(value) || angular.isUndefined(regExp) || !regExp.test(value);
};
}
};
})
这是一个更新的 JSFiddle:
http://jsfiddle.net/8Lk3pqep/2/