typescript - Angular Sử dụng Biểu mẫu của Thành phần Con trong Biểu mẫu Lồng nhau của Thành phần Cha
Cách tốt nhất để đặt một biểu mẫu ChildComponent vào biểu mẫu của Parent Component là gì? Chúng tôi đang sử dụng Angular 8 mới nhất vào năm 2019. Các phương pháp dưới đây sau khi nghiên cứu thì không hoàn toàn hoạt động.
Thành phần cha:
ngOnInit() {
this.parentForm = this.fb.group({
childForm1: etc
})
Thành phần Con:
this.ChildForm = this.formBuilder.group({
'streetNumber': [null, [Validators.required, Validators.maxLength(32)]],
'streetType': [null, [Validators.maxLength(8)]],
'city': [null, [Validators.maxLength(32)]],
'state': [null, [Validators.maxLength(16)]],
'postalCode': [null, [Validators.maxLength(16)]],
}, { validator: atLeastOneLocationRequired })
}
Phương pháp 1:
Phương pháp này, https://itnext.io/partial-reactive-form-with-angular-components-443ca06d8419 sau khi kiểm tra kỹ lưỡng cho biết ParentForm là hợp lệ, ngay cả khi Form Con không hợp lệ. Điều này không nên xảy ra.
ngOnInit() {
this.parent = this.fb.group({
fullName: null
})
}
formInitialized(name: string, form: FormGroup) {
this.checkoutForm.setControl(name, form);
}
Phương pháp 2:
Phương pháp 2 sử dụng ViewChild, điều này nghe có vẻ là thực hành không tốt. https://davembush.github.io/attaching-an-angular-child-component-s-form-to-a-parent/
@ViewChild(ChildComponent) childComponent: ChildComponent;
And now in ngAfterViewInit() we can add the child’s FormGroup as an additional “control” and set the parent FormGroup to the parent control’s FormGroup.
ngAfterViewInit() {
this.form.addControl('childForm', this.childComponent.form);
this.childComponent.form.setParent(this.form);
}
Vậy thực hành chính thức tốt nhất của Angular trong Angular 8 là gì?
Câu trả lời #1
Tôi đã tạo một kịch bản nhỏ theo vấn đề của bạn.
thành phần cha :
HTML :
<form [formGroup]="form">
<app-child [form]="form"></app-child>
<pre>{{form.value | json}}</pre>
</form>
TS :
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
form: FormGroup;
constructor (private fb: FormBuilder) {}
ngOnInit() {
this.form = this.fb.group({
childForm1: '',
streetNumber: [null, [Validators.required, Validators.maxLength(32)]],
streetType: [null, [Validators.maxLength(8)]],
city: [null, [Validators.maxLength(32)]],
state: [null, [Validators.maxLength(16)]],
postalCode: [null, [Validators.maxLength(16)]],
})
}
}
childComponent :
HTML :
<div [formGroup]="form">
<input formControlName="streetNumber"><br>
<input formControlName="streetType"><br>
<input formControlName="city"><br>
<input formControlName="state"><br>
<input formControlName="postalCode">
</div>
TS :
import { Component, OnInit, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
@Input() form: FormGroup;
constructor() { }
ngOnInit() {
}
}
Liên kết hoạt động: https://stackblitz.com/edit/angular-gjrphg
Liên kết cập nhật cho nhiều child: https://stackblitz.com/edit/angular-svnqfh?file=src/app/app.component.html
Câu trả lời số 2
Sau nhiều cuộc thảo luận và thử nghiệm, nhóm của tôi đã chọn một cách tiếp cận gần như là phương án đầu tiên, tức là thành phần con định nghĩa subform và nhóm form tương ứng. Nhưng chúng tôi không thiết lập form control bằng @ViewChild() và AfterViewInit. Thay vào đó, chúng tôi truyền form của cha xuống thành phần con và để thành phần con thiết lập liên kết. Điều này là vì chúng tôi có một thành phần con được sử dụng trong nhiều thành phần cha khác nhau và việc lặp lại đoạn mã AfterViewInit sẽ nhanh chóng trở nên nhàm chán. Ngoài ra, cách tiếp cận này cũng hoạt động nếu form của cha được bao bọc trong một directive *ngIf vì việc kết nối xảy ra khi thành phần con được khởi tạo, chứ không phải trước đó (không còn những trò rắc rối với @ViewChild() set childComponent() {} nữa).
<!-- parent form -->
<app-child-form [parent]="form"></app-child-form>
// Child component
@Component({
selector: 'app-child-form',
templateUrl: './child-form.component.html',
})
export class ChildComponent {
@Input()
parent!: FormGroup;
form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
// ...
});
}
ngOnInit() {
this.parent.addControl('child-form', this.form);
this.form.setParent(this.parent);
}
}
