我有一个表单元素,我可以在其中动态添加和删除值。
例如,在下面的代码域中,可以使用addDomain和removeDomain
添加和删除 <div *ngFor="let item of company.domains">
<div class="row">
<div class="col-lg-9">
<input type="text" class="form-control" ngControl="domainC" [(ngModel)]="company.domains[i]">
</div>
<div class="col-lg-3 pull-left">
<a (click)="removeDomain(i)"> <i class="fa fa-times"></i></a>
<a (click)="addDomain()"> <i class="fa fa-plus"></i></a>
</div>
</div>
</div>
我需要在提交时验证这些,因为所有添加的值都是必需的。我在角度2中使用Control,但无法弄清楚如何对这些元素应用验证,任何帮助都将不胜感激。
答案 0 :(得分:3)
您可以将表单绑定到表单模型
<form [ngFormModel]="form">
<div *ngFor="let item of controls let idx=index">
<div class="row">
<div class="col-lg-9">
<label>{{item.name}}</label><input type="text" class="form-control" [ngControl]="item.name" [(ngModel)]="values[item.name]">
{{item.control.errors | json}}
</div>
<div class="col-lg-3 pull-left">
<div><button (click)="removeDomain(i)">remove</button></div>
</div>
</div>
</div>
<hr>
<div>
<label>control name</label><input #nameInput>
<label>validator</label><select #validatorInput>
<option>required</option>
<option>minLength</option>
<option>maxLength</option>
</select>
<label>length</label><input type="number" #lengthInput>
<button (click)="addDomain(nameInput.value, validatorInput.value, lengthInput.value)">add</button>
</div>
export class App {
form:ControlGroup;
controls [
{ name: 'name', control: new Control('', Validators.required) },
{ name: 'password', control: new Control('', Validators.minLength(3))}
];
values = {
name: '',
password: '',
}
constructor(fb:FormBuilder) {
this.form = fb.group();
this.name = 'Angular2 (Release Candidate!)'
this.controls.map((item) => {
console.log('map item', item);
this.form.addControl(item.name, item.control);
});
}
removeDomain(i) {
this.values[this.controls[i].name]=undefined;
this.form.removeControl(this.controls[i].name);
this.controls.splice(i);
this.form.controls.forEach(c => c.updateValueAndValidity());
}
addDomain(name, validator, length) {
this.values[name] = '';
var validator;
if(length) {
validator = Validators[validator](length);
} else {
validator = Validators[validator];
}
let newCtl = new Control('', validator);
this.controls.push({name: name, control: newCtl});
this.form.addControl(name, newCtl);
//this.controls.forEach(c => this.form.controls[c.name].updateValueAndValidity());
}
}
答案 1 :(得分:2)
我找到了解决方案。这个问题与控制命名有关。从中间删除行时,表索引将重新启动并添加具有重复控件名称的另一行。
添加了一个总是递增并将其分配给详细对象的计数器。
addRow() {
this.details.push(<IDetail>{controlIndex:this.iRow});
this.rowValidateForm(this.iRow++, 'add');
}
在删除时从详细信息对象中获取计数器,并从组中删除具有计数器名称的控件。
removeRow(index) {
let controlIndex = this.details[index].controlIndex;
this.details.splice(index, 1);
this.rowValidateForm(controlIndex, 'remove');
}
在视图中使用countrolIndex替换FormControlName中的行索引。
答案 2 :(得分:0)
如果要在视图控制器中以编程方式执行验证,可以在视图中引用控件并在更改时将其传递给控制器。类似的东西:
<h:form>
<p:tabView>
<p:tab title="title">
<h:form>
<p:commandButton actionListener="... />
</h:form>
</p:tab>
</p:tabView>
</h:form>
控制器:
<input type="text" class="form-control" ngControl="domainC" #domainCControl="ngForm" [(ngModel)]="company.domains[i]" (change)="onDomainInputChanged(domainCControl)">
<div [hidden]="domainCControl.valid">Control invalid</div>
但是您可能希望在可以在其他地方重用的专用指令中实现验证器:
onDomainInputChanged(control: NgControlName) {
// You have access to control.control.validatorFn here
}
指令:
<input type="text" class="form-control" ngControl="domainC" [(ngModel)]="company.domains[i]" validate-domain-control >