【发布时间】:2020-03-31 23:44:49
【问题描述】:
基于这两个网址:
- https://brophy.org/post/nested-reactive-forms-in-angular2/(1)
- https://stackblitz.com/edit/monolithic-reactive-form-async-fill(2)
我想要:
- 一个主组件
- 带有 ListComponent
- 和一个 ListItemComponent
MasterComponent.ts
public data: Data;
public form: FormGroup = this.fb.group({});
formInitialized(name: string, form: FormGroup) {
this.form.addControl(name, form);
}
MasterComponent.html
<app-list [parentForm]="form"
[items]="data.items"
(formReady)="formInitialized('items', $event)"></app-list>
ListComponent.ts
@Input() parentForm: FormGroup;
@Input() items: item[];
@Output() formReady = new EventEmitter<AbstractControl>()
public itemsForm: FormArray;
formInitialized(itemForm: FormGroup) {
debugger;
this.itemsForm.push(itemForm);
}
ngOnInit() {
debugger;
this.itemsForm = new FormArray([]);
this.formReady.emit(this.itemsForm);
}
ListComponent.html
<div [formGroup]="parentForm">
<div formArrayName="items">
<ng-template let-item let-last="last" let-i="index" ngFor [ngForOf]="items">
<app-item [itemsForm]="parentForm.controls.items"
[item]="item"
(formReady)="formInitialized($event)">
</app-item>
</ng-template>
</div>
</div>
item.component.ts
@Input() itemsForm: FormArray;
@Input() item: Item;
@Output() formReady = new EventEmitter<AbstractControl>()
public itemForm: FormGroup;
ngOnInit() {
this.itemForm = this._formBuilder.group({title: [item.title || '', Validators.required],});
this.formReady.emit(this.itemForm);
}
item.component.html
<div class="md-padding" [formGroup]="itemForm">
<mat-form-field flex>
<input #title
name="title"
matInput
type="text"
placeholder="Title"
formControlName="title"
maxlength="150"
required />
<mat-error *ngIf="title.pristine || !title.errors">
<div *ngIf="title.errors?.required">
this field is required.
</div>
<div *ngIf="title.errors?.maxlength">
max length is 150.
</div>
</mat-error>
<mat-hint align="end">{{title.value.length}} / 150</mat-hint>
</mat-form-field>
</div>
我的代码有错误:
MasterComponent.html:12 ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'Items: [object Object],[object Object]core.js:8445)
at expressionChangedAfterItHasBeenCheckedError (core.js:8433)
at checkBindingNoChanges (core.js:8535)
at checkNoChangesNodeInline (core.js:11403)
at checkNoChangesNode (core.js:11390)
at debugCheckNoChangesNode (core.js:11997)
at debugCheckDirectivesFn (core.js:11925)
at Object.eval [as updateDirectives] (MasterComponent.html:12)
at Object.debugUpdateDirectives [as updateDirectives] (core.js:11914)
at checkNoChangesView (core.js:11289)
我喜欢子组件负责将 formGroup 提供给主组件1 的概念。 解决方案1 的问题是子组件无法更新主组件(参见问题https://github.com/brophdawg11/ng-playground/issues/5)。 所以我用解决方案2调整了解决方案1。
但它不起作用。有没有办法解决这个问题?或者你有什么好的教程要提议?
谢谢
【问题讨论】:
-
这对我来说很可疑
(formReady)="formInitialized($event)"。看起来您使用@Output()绑定将内部引用传递给其他组件,然后该组件的内部状态被外部人员更改。这解释了为什么您会收到更改错误。 -
我希望我的子组件通过添加新属性来更新 MasterForm。这样子组件在其他组件中的复用性会更高。所以是的,ListComponent formInitialized 将新的 FormArray 发送到 MasterComponent 和 ItemComponent formInitialized 发送新的 FormGroup 以添加到 ListComponent FormArray。我愿意改变很多事情,我的主要观点是保持对子组件的责任,将 AbstractControl 发送到父组件。
标签: angular typescript angular-reactive-forms