我正在尝试更新从服务收集的嵌套数据。*ngFor我通过使用填充输入值以 html 表单显示数据库数据。
当我尝试提交这个时,它总是给我null,因为我还没有真正接触过这些领域。奇怪的是,当我为该字段输入新值或编辑给定值时,它确实通过了它们。在正常情况下,这正是我想要的。
但在这种情况下,如果我只编辑第一个字段和submit表单,它只会传递第一个字段的值并null为其他字段提供。
换句话说,用表单数据覆盖现有数据对我来说是危险的,因为除了第一个数据之外,它会用 null 覆盖所有数据。
- - - - - 编辑 - - - - -
下面的代码现在可以使用 FormBuilder。它通过循环主数组长度的循环生成这些字段(下图)。
用清晰的语言:数组包含可变数量的对象。每个对象都有:
- 标题(第一个输入字段)
- 标头大小(第二个输入)
- 可变数量的段落
每个组都用一个<hr>标签封闭。
您还可以看到我填写了each输入字段的value标签,使用*ngFor(见下面的 html)。
现在的问题是,如果我submit在不更改任何值的情况下创建表单,我会得到一个包含所有正确键的对象数组,但它们的所有值都设置为,null因为我实际上没有编辑这些字段。
如果我提交,我想检索一组对象及其值,即使我没有编辑一个对象。
否则我将不得不编写一个复杂的功能来仅覆盖 value 所在的当前数据is not null。
所以我的实际问题是:
即使我没有编辑(触摸)单个字段,是否有办法检索所有值?还是我应该使用其他方法?
如果我submit得到这个表格(因为我实际上没有编辑过一些东西):
HTML:
<h3>Description</h3>
<form [formGroup]="colForm" (submit)="updateCol(colForm); $event.preventDefault()">
<div class="margin-bottom-30" *ngFor="let col of overall_data.value.cols; let i=index">
<div [formGroupName]="i">
<div class="form-group" formGroupName="title">
<input class="form-control" type="text" formControlName="text" name="text" value="{{ col.title.text }}">
<input type="number" class="form-control" formControlName="size" name="size" min="1" max="5" value="{{ col.title.size }}">
</div>
<div formGroupName="body">
<div formArrayName="paragraphs">
<div *ngFor="let p of col.body.paragraphs; let pi=index">
<div class="form-group" [formGroupName]="pi">
<textarea class="form-control" formControlName="text" cols="30" rows="10" value="{{ p.text }}"></textarea>
<div *ngIf="p.classes" formArrayName="classes">
<div *ngFor="let class of p.classes">
<input type="text" name="class" class="form-control" value="{{ class }}">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<hr>
</div>
<div class="form-group">
<input type="submit" class="btn btn-custom" value="Save">
</div>
</form>
打字稿文件:
export class AdminWebComponent implements OnInit {
overall_data: any;
id: string;
errorMessage: string;
colForm: FormArray = this._fb.array([]);
constructor(private _skillsService: SkillsService, private _fb: FormBuilder) {
// work with form groups: https://scotch.io/tutorials/how-to-build-nested-model-driven-forms-in-angular-2
}
ngOnInit(): void {
this._skillsService.getByKey('web')
.subscribe(
overall_data => this.overall_data = overall_data,
error => this.errorMessage = error,
() => {
this.id = this.overall_data['id'];
// cols
for (var i = 0; i < this.overall_data.value.cols.length; ++i) {
this.colForm.push(this.initCols()) // in for loop so we can have a dynamic amount of cols
}
// charts
}
);
}
// init functions
initCols(): any {
return this._fb.group({ // need to be called twice because array has 2 items, makes this dynamic?
title: this._fb.group({
text: [""],
size: [0]
}),
body: this._fb.group({
paragraphs: this._fb.array([
this.initParagraphs(),
this.initParagraphs()
])
})
})
}
initParagraphs(): any {
return this._fb.group({
text: [""],
classes: this._fb.array([])
})
}
// update functions
updateCol(colForm: any): void {
console.log(this.id);
console.log(colForm.value);
// this._skillsSevice()
// .
}
-------已解决--------
这并不简单(对我来说),但我必须做的事情真的很明显......我必须删除value binding我在 中所做的HTML,而是使用 for 循环用 formbuilder 填充值。
似乎尝试将表单生成器控件与 HTML 中生成的值结合起来并不是一个好主意,也不是很合乎逻辑。最好在 TypeScript 文件中而不是在 HTML 中处理我的复杂数据。
打字稿调整:
...
ngOnInit(): void {
this._skillsService.getByKey('web')
.subscribe(
overall_data => this.overall_data = <ISkills>overall_data,
error => this.errorMessage = error,
() => {
this.id = this.overall_data['id'];
// cols
for (var i = 0; i < this.overall_data.value.cols.length; ++i) {
this.colForm.push(this.initCols(this.overall_data.value.cols[i])) // in for loop so we can have a dynamic amount of cols
}
// charts
}
);
}
// init functions
initCols(cols: ICols): any {
// console.log(cols);
return this._fb.group({ // need to be called twice because array has 2 items, makes this dynamic?
title: this._fb.group({
text: [ cols.title.text ],
size: [ cols.title.size ]
}),
body: this._fb.group({
paragraphs: this.initParagraphs(cols.body.paragraphs)
})
})
}
initParagraphs(paragraphs: IParagraph[]): any {
let arr: FormArray = this._fb.array([]);
for (var i = 0; i < paragraphs.length; ++i) {
arr.push(
this._fb.group({
text: [ paragraphs[i].text ],
classes: this._fb.array([ paragraphs[i].classes ])
})
)
}
return arr;
}
...

