我有一个有形式的有角度的应用程序。我有一个输入字段,用户可以在其中输入字符串并单击添加按钮,然后分析输入,对其进行验证并将其添加到表单模型中。输入元素的[(ngModel)]绑定到组件上的瞬态变量属性。成功验证后,瞬时变量的值将被清除,因此用户可以输入要添加到模型中的另一项。
瞬态变量是必填字段的输入字段,因为如果您从未向模型添加新项目,则无法提交表单。
我想更改输入元素的 valid 条件,以便在模型中添加至少一个新项目时,输入元素字段可以保留为空白,并且我可以成功提交表单
form.component.ts:
import { Component, OnInit } from '@angular/core';
import { Model } from './model';
@Component({
selector: 'app-form',
templateUrl: './form.component.html',
styleUrls: ['./form.component.css']
})
export class FormComponent implements OnInit {
model: Model;
transientItem: string;
constructor() { }
get diagnostic() { return JSON.stringify(this.model); }
ngOnInit() {
this.model = new Model([]);
}
onSubmit() {
//handle submit logic
}
addItem() {
const items = this.transientItem.split(' ');
if (items.length === 3) {
const newItem = {
itemName: items[0],
itemValue: items[1],
itemLabel: items[2]
};
this.model.items.push(newItem);
this.transientItem = '';
} else {
alert('invalid item format');
}
}
}
form.component.html:
<form (ngSubmit)="onSubmit()" #myForm="ngForm">
{{diagnostic}}
<div class="form-group">
<input type="text" class="form-control" required [(ngModel)]="transientItem" name="item" #item="ngModel" />
<button type="button" (click)="addItem()">Add</button>
</div>
<button type="submit" [disabled]="!myForm.form.valid">Submit</button>
</form>
model.ts:
export class Model {
constructor(
public items: {
itemName: string,
itemValue: string,
itemLabel: string
}[]
) { }
}
当前行为:如果输入的值为空,则“提交”按钮将被禁用,但是一旦我在文本字段中输入内容,我就可以提交表单...
预期的行为:只有当我的模型的items属性中至少有1个项目时,我才能提交表单。如果模型中有1个项目,但将输入字段留空,则由于已经添加了一个项目,我仍然可以提交表单。
答案 0 :(得分:0)
我几乎总是使用ReactiveForms
,因为API提供了许多有用的工具来构建简单到复杂的表单。在您的情况下,解决方案可能类似于:
import { Component } from '@angular/core';
import { FormControl, FormGroup, FormArray, Validators } from '@angular/forms';
@Component({
selector: 'my-app',
template: `
<form [formGroup]="form">
<input formControlName="newItem">
<button type="button" (click)="addItem()" [disabled]="!item.valid">ADD</button>
<hr>
<button type="button" (click)="submit()" [disabled]="!items.valid">SUBMIT</button>
<hr>
<ul>
<li *ngFor="let item of items.controls; let i = index">{{ item.value }} - <button type="button" (click)="removeItem(i)">DELETE</button></li>
</ul>
</form>
`
})
export class AppComponent {
form: FormGroup;
get item() {
return this.form.get('newItem') as FormControl;
}
get items() {
return this.form.get('items') as FormArray;
}
constructor() {
this.form = new FormGroup({
newItem: new FormControl('', Validators.required),
items: new FormArray([], Validators.required),
})
}
addItem() {
this.items.push(new FormControl(this.item.value));
this.item.reset('');
}
removeItem(i: number) {
this.items.removeAt(i);
}
submit() {
console.log(this.form.value);
}
}
让我们解释一下我们在做什么。
我们正在创建一个新的FormControl
,启用ADD
按钮需要。
newItem: new FormControl('', Validators.required)
以及我们的HTML
<button type="button" (click)="addItem()" [disabled]="!item.valid">ADD</button>
我们还创建了一个新的FormArray
来存储我们要保留的所有新项目,同时我们使用所需的验证程序来使用我们的SUBMIT
按钮的状态>
items: new FormArray([], Validators.required)
进出HTML
<button type="button" (click)="submit()" [disabled]="!items.valid">SUBMIT</button>
是的,我们的整个表格不会是VALID
,但我们不在乎。当您按下SUBMIT
按钮时,我们将使用this.form.value['items']
提取项目,这将是我们添加的项目数组。
这里也是stackblitz。