带有 ng-repeat 验证的 AngularJS 多个表单 [英] AngularJS multiple forms with ng-repeat validation
问题描述
我使用 ng-form 作为父表单,使用子 mg-form 使用 ng-repeat 进行验证.
<div ng-repeat="字段中的字段"><div ng-form="subform"><input...></div>
并像这样验证:
if ($scope.form.subform.$invalid && !$scope.form.subform.$error.required) {//做点什么...}
(这是一个非常简单的例子,对于不同的输入类型和不同的名称,我有更多不同的子表单,例如 input[text] 被命名为 TextForm,input[numeric] 是 NumericForm 等)
如果只有现场,一切都按预期进行.但是如果 ng-repeat 生成多个字段,验证只会触发最后一个子表单,其他的会被忽略.
有没有办法循环遍历所有子表单以检查其中一个是否无效?
此外,我正在标记所有未填写的必填字段,如下所示:
if ($scope.form.$error.required) {angular.forEach($scope.form.$error.required,函数(对象,索引){$scope.form.$error.required[index].$setDirty();});}
所以如果我的字段是这样完成的:
....ng-form="TextForm" ng-class="{ 'has-error': TextForm.$dirty && TextForm.$invalid }"....
即使有很多同名的子表单,它也会标记所有的子表单.
也许我可以对无效字段做类似的事情?虽然尝试了很多东西,但没有任何效果......
对此的解决方案是创建一个指令,将 ngModelController
的错误分配给每个 ng-重复
输入.
下面是获取每个子表单错误的可能实现.演示
JAVASCRIPT(指令)
.directive('ngModelError', function($parse, $timeout) {返回 {要求: ['ngModel', 'form'],链接:功能(范围,元素,属性,ctrls){var ngModel = ctrls[0],ngForm = ctrls[1],fieldGet = $parse(attr.ngModelError),fieldSet = fieldGet.assign,字段 = fieldGet(范围);$超时(功能(){field.$error = ngModel.$error;field.ngForm = ngForm;字段集(范围,字段);});}};});
HTML
<br><button type="submit" class="btn btn-primary">提交</button></表单>
JAVASCRIPT(控制器)
请注意字段的结构:
.controller('Ctrl', function($scope) {$scope.fields = {电子邮件: {类型:'电子邮件',占位符:'输入电子邮件',是必需的:真,标签:'电子邮件地址'},密码: {类型:'密码',占位符:'输入密码',是必需的:真,标签:'密码'}};$scope.submit = 函数(表单,字段){form.$dirty = true;if(form.$valid) {//做任何事} 别的 {//访问电子邮件字段的 ngFormconsole.log(fields.email.ngForm);//访问电子邮件字段的错误console.log(fields.email.$error);//访问 ngForm 以获取密码字段console.log(fields.password.ngForm);//访问密码字段错误console.log(fields.password.$error);}};})
I am using ng-form as a parent form and child mg-forms for validation with ng-repeat.
<div ng-form="form">
<div ng-repeat="field in fields">
<div ng-form="subform"><input...></div>
</div>
</div>
And validating like this:
if ($scope.form.subform.$invalid && !$scope.form.subform.$error.required) {
// Do something...
}
(this is very simplified example, I have more different subforms for different input types and with different names, e.g. input[text] is named as a TextForm, input[numeric] is NumericForm etc.)
Everything works as expected if there is only on field. But if ng-repeat generates multiple fields, validation triggers only the last subform, others gets ignored.
Is there a way of cycling through all subforms to check if one of them is invalid?
Also, I am marking all unfilled required fields like this:
if ($scope.form.$error.required) {
angular.forEach($scope.form.$error.required,
function (object, index) {
$scope.form.$error.required[index].$setDirty();
}
);
}
So if my fields are done like this:
....ng-form="TextForm" ng-class="{ 'has-error': TextForm.$dirty && TextForm.$invalid }"....
And it marks all the subforms even if there are many of the same ones with the same name.
Maybe I could do something similar with invalid fields? Though tried many things, nothing worked...
A solution for this is to create a directive that assigns the ngModelController
's error to a variable in each ng-repeat
input.
Below is a possible implementation to get the errors of each subForm. DEMO
JAVASCRIPT (directive)
.directive('ngModelError', function($parse, $timeout) {
return {
require: ['ngModel', 'form'],
link: function(scope, elem, attr, ctrls) {
var ngModel = ctrls[0],
ngForm = ctrls[1],
fieldGet = $parse(attr.ngModelError),
fieldSet = fieldGet.assign,
field = fieldGet(scope);
$timeout(function() {
field.$error = ngModel.$error;
field.ngForm = ngForm;
fieldSet(scope, field);
});
}
};
});
HTML
<form name="form" ng-submit="submit(form, fields)" novalidate>
<div ng-form="subForm" ng-repeat="field in fields"
ng-class="{'has-error': subForm.$invalid && form.$dirty}">
<label class="control-label">{{field.label}}</label>
<input type="{{field.type}}" placeholder="{{field.placeholder}}"
ng-model="field.model" name="field"
ng-required="field.isRequired" class="form-control"
ng-model-error="field" />
</div>
<br>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
JAVASCRIPT (controller)
Please take note how the fields are structure:
.controller('Ctrl', function($scope) {
$scope.fields = {
email: {
type: 'email',
placeholder: 'Enter email',
isRequired: true,
label: 'Email Address'
},
password: {
type: 'password',
placeholder: 'Enter password',
isRequired: true,
label: 'Password'
}
};
$scope.submit = function(form, fields) {
form.$dirty = true;
if(form.$valid) {
// do whatever
} else {
// accessing ngForm for email field
console.log(fields.email.ngForm);
// accessing errors for email field
console.log(fields.email.$error);
// accessing ngForm for password field
console.log(fields.password.ngForm);
// accessing errors for password field
console.log(fields.password.$error);
}
};
})
这篇关于带有 ng-repeat 验证的 AngularJS 多个表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!