输入值未正确填写在 FormArray 中
input values does not fill correctly in FormArray
我无法将正确的值填充到 FormArray 的输入字段中。这是我的 html:
<div formArrayName="roles" *ngFor="let role of roles.controls; let i=index">
<div [formGroupName]="i">
<div class="form-group row">
<label class="col-md-2 col-form-label" attr.for="{{'roleNameId' + i}}">Role Name {{i+1}}</label>
<div class="col-md-6">
<input class="form-control"
attr.id="{{'roleNameId' + i}}"
type="text"
formControlName="roleName">
</div>
<label class="col-md-2 col-form-label" attr.for="{{'identifierId' + i}}">
<input
type="checkbox"
attr.id="{{'identifierId' + i}}"
formControlName="identifier"> identifier
</label>
<div class="col-md-2">
<button type="button" (click)="removeRole(i)" class="btn btn-danger oi oi-trash"></button>
</div>
</div>
</div>
</div>
所以这个 html 被渲染了 x 次,这取决于我拥有的角色数量。这工作得很好,没有显示错误。
但问题是:当我删除一个不是数组最后一个的角色时,填充正确角色的输入字段会发生变化。
以下是角色:
例如,当我删除角色 2 时,表单如下所示:
角色 2 被正确删除,但角色 3 消失了,最后两个角色使用最后一个角色 (role8) 的名称
为什么会这样?当我查看保存所有角色的 formArray 时,该数组具有正确的值,证据如下:
为什么视图中没有显示正确的值?感谢您的帮助
编辑:这是相关的打字稿代码:
this.sourcesForm = this.fb.group({
sourceName: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(255)]],
sourceType: ['QUERY'],
dsl: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(255)]],
list: [''],
roles: this.fb.array([this.buildRole()]),
database: [''],
});
// save roles to temporary variable to map for the roles Formarray
let roles = [];
dslStatement.roles.forEach(role => {
let oneRole = {
roleName: role.name,
identifier: true
}
if (role.role === 'IDENTIFIER')
oneRole.identifier = true;
else
oneRole.identifier = false
roles.push(oneRole);
});
// convert the variable to FormGroups, then the FormGroups to one FormArray
// and at last set the FormArray to the roles of sourcesForm
const rolesFormGroups = roles.map(roles => this.fb.group(roles));
const rolesFormArray = this.fb.array(rolesFormGroups);
this.sourcesForm.setControl('roles', rolesFormArray);
buildRole(): FormGroup {
return this.fb.group({
roleName: '',
identifier: true
});
}
addRole() {
this.roles.push(this.buildRole());
}
removeRole(i: number) {
this.roles.removeAt(i);
console.log(this.roles.value);
console.log(this.roles.controls);
}
更新
我建立了一个 stackblitz 试图在这里演示这个问题:https://stackblitz.com/edit/angular-dk-formarray
它使用 Angular 5.0 没有 有问题。
我 能够使用我上面提到的课程中的应用程序重现此内容 (Angular 4):
删除 "a" 行后,我得到:
注意 "a" 不见了,但现在我有两个 "c" 而不是 "b" 和 "c"。
有趣的是,如果我保存然后返回页面,它会正确显示 "b" 和 "c"。
所以这似乎是一个错误,已在 Angular 5.
中修复
我能够在 Angular 4.x 中找到适合我的 "work around" 4.x:
deleteTag(index: number): void {
this.tags.removeAt(index);
this.productForm.setControl('tags', this.fb.array(this.tags.value || []));
}
您也许可以做类似的事情(但我不确定您的 roles
是否像我的 tags
一样设置?)
但是你最好还是搬到 Angular 5.
试试这个:
addRole() {
this.roles = this.sourcesForm.get('roles') as FormArray;
this.roles.push(this.buildRole());
}
而不是
addRole() {
this.roles.push(this.buildRole());
}
我无法将正确的值填充到 FormArray 的输入字段中。这是我的 html:
<div formArrayName="roles" *ngFor="let role of roles.controls; let i=index">
<div [formGroupName]="i">
<div class="form-group row">
<label class="col-md-2 col-form-label" attr.for="{{'roleNameId' + i}}">Role Name {{i+1}}</label>
<div class="col-md-6">
<input class="form-control"
attr.id="{{'roleNameId' + i}}"
type="text"
formControlName="roleName">
</div>
<label class="col-md-2 col-form-label" attr.for="{{'identifierId' + i}}">
<input
type="checkbox"
attr.id="{{'identifierId' + i}}"
formControlName="identifier"> identifier
</label>
<div class="col-md-2">
<button type="button" (click)="removeRole(i)" class="btn btn-danger oi oi-trash"></button>
</div>
</div>
</div>
</div>
所以这个 html 被渲染了 x 次,这取决于我拥有的角色数量。这工作得很好,没有显示错误。
但问题是:当我删除一个不是数组最后一个的角色时,填充正确角色的输入字段会发生变化。
以下是角色:
例如,当我删除角色 2 时,表单如下所示:
角色 2 被正确删除,但角色 3 消失了,最后两个角色使用最后一个角色 (role8) 的名称
为什么会这样?当我查看保存所有角色的 formArray 时,该数组具有正确的值,证据如下:
为什么视图中没有显示正确的值?感谢您的帮助
编辑:这是相关的打字稿代码:
this.sourcesForm = this.fb.group({
sourceName: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(255)]],
sourceType: ['QUERY'],
dsl: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(255)]],
list: [''],
roles: this.fb.array([this.buildRole()]),
database: [''],
});
// save roles to temporary variable to map for the roles Formarray
let roles = [];
dslStatement.roles.forEach(role => {
let oneRole = {
roleName: role.name,
identifier: true
}
if (role.role === 'IDENTIFIER')
oneRole.identifier = true;
else
oneRole.identifier = false
roles.push(oneRole);
});
// convert the variable to FormGroups, then the FormGroups to one FormArray
// and at last set the FormArray to the roles of sourcesForm
const rolesFormGroups = roles.map(roles => this.fb.group(roles));
const rolesFormArray = this.fb.array(rolesFormGroups);
this.sourcesForm.setControl('roles', rolesFormArray);
buildRole(): FormGroup {
return this.fb.group({
roleName: '',
identifier: true
});
}
addRole() {
this.roles.push(this.buildRole());
}
removeRole(i: number) {
this.roles.removeAt(i);
console.log(this.roles.value);
console.log(this.roles.controls);
}
更新 我建立了一个 stackblitz 试图在这里演示这个问题:https://stackblitz.com/edit/angular-dk-formarray
它使用 Angular 5.0 没有 有问题。
我 能够使用我上面提到的课程中的应用程序重现此内容 (Angular 4):
删除 "a" 行后,我得到:
注意 "a" 不见了,但现在我有两个 "c" 而不是 "b" 和 "c"。
有趣的是,如果我保存然后返回页面,它会正确显示 "b" 和 "c"。
所以这似乎是一个错误,已在 Angular 5.
中修复我能够在 Angular 4.x 中找到适合我的 "work around" 4.x:
deleteTag(index: number): void {
this.tags.removeAt(index);
this.productForm.setControl('tags', this.fb.array(this.tags.value || []));
}
您也许可以做类似的事情(但我不确定您的 roles
是否像我的 tags
一样设置?)
但是你最好还是搬到 Angular 5.
试试这个:
addRole() {
this.roles = this.sourcesForm.get('roles') as FormArray;
this.roles.push(this.buildRole());
}
而不是
addRole() {
this.roles.push(this.buildRole());
}