我的队友和我正在学习AngularJS,目前正在尝试进行一些简单的表单字段验证。我们意识到有很多方法可以做到这一点,我们已经尝试了
对我而言,指令方法似乎是最“正确”的。对于#3,我们遇到了必须将验证结果传递给错误元素(span
兄弟)的问题。做一些范围杂耍很简单,但是将span
放在指令中似乎“更正确”,并捆绑整个表单控件。我们遇到了几个问题,我希望StackOverflow社区对我们的解决方案提出意见和/或澄清任何误解。
var PATTERN_NAME = /^[- A-Za-z]{1,30}$/;
module.directive("inputName", [
function () {
return {
restrict: "E",
require: "ngModel",
scope: {
fieldName: "@",
modelName: "=",
labelName: "@",
focus: "@"
},
template: '<div>' +
'<label for="{{fieldName}}">{{labelName}}</label>' +
'<input type="text" ng-model="modelName" id="{{fieldName}}" name="{{fieldName}}" placeholder="{{labelName}}" x-blur="validateName()" ng-change="validateName()" required>' +
'<span class="inputError" ng-show="errorCode">{{ errorCode | errorMsgFltr }}</span>' +
'</div>',
link: function (scope, elem, attrs, ngModel)
{
var errorCode = "";
if (scope.focus == 'yes') {
// set focus
}
scope.validateName = function () {
if (scope.modelName == undefined || scope.modelName == "" || scope.modelName == null) {
scope.errorCode = 10000;
ngModel.$setValidity("name", false);
} else if (! PATTERN_NAME.test(scope.modelName)) {
scope.errorCode = 10001;
ngModel.$setValidity("name", false);
} else {
scope.errorCode = "";
ngModel.$setValidity("name", true);
}
};
}
};
}
]);
用作
<form novalidate name="addUser">
<x-input-name
label-name="First Name"
field-name="firstName"
ng-model="firstName"
focus="yes"
model-name="user.firstName">
</x-input-name>
<x-input-name
label-name="Last Name"
field-name="lastName"
ng-model="lastName"
model-name="user.lastName">
</x-input-name>
...
</form>
首先,因为AngularJS指令会覆盖form
和input
,所以我们需要访问ngModel API(ngModelController
)以允许现在嵌套的input
能够将有效性传达给父FormController
。因此,我们必须require: "ngModel"
,它成为ngModel
函数的link
选项。
其次,即使fieldName
和ngModel
被赋予相同的值,我们也必须单独使用它们。单向绑定(1WB)fieldName
用作属性值。我们发现我们无法在ngModel
指令中使用花括号。此外,我们无法使用带有ngModel
和的1WB输入,我们无法使用双向绑定(2WB)输入,其值应为静态。如果我们使用单个2WB输入,则模型可以正常工作,但id
和name
等属性将成为赋予表单控件的值。
最后,因为我们有时会以相同的形式重复使用该指令(例如,名字和姓氏),所以我们必须传递像focus
参数这样的属性。
就个人而言,我还希望在onblur
函数中看到使用JavaScript绑定的onchange
和link
事件,但我不确定如何从内部访问模板标记link
,特别是在更大的DOM之外/不知道。