Angular Parent Form with Child Form Component,如何让Child知道Parent何时提交?

Angular Parent Form with Child Form Component, how to Let Child Know when Parent is submitted?

我正在以这种方式使用带有子组件窗体的父窗体。

如何让子组件知道父表单何时提交了按钮 Ng? parentForm 变量在子组件中作为变量。有没有办法,我可以将 parentFormGroup 作为一个事件来判断?

当子窗体知道后,我想计算一些复杂的值(不在窗体中),并将它们发送给父组件。

父组件:

 ngOnInit() {
    this.parentForm = this.fb.group({
       'customerName': [null, [Validators.required]],
       'phoneNumber': [null, [Validators.required]],
    })

 <form [formGroup]="parentForm" (ngSubmit)="onSubmit()">
    <app-child [form]="parentForm"></app-child>
    <button type="submit">Purchase</button>
 </form>

子组件:

需要知道在这个组件中,parentForm什么时候提交。

@Input() parentForm: FormGroup;

ngOnInit() {
    this.parentForm.addControl('address', new FormControl(Validators.required));
    this.parentForm.addControl('city', new FormControl(Validators.required));
 }

选项 1
使用 @ViewChild 并获取子组件引用和 运行 它的方法。

例子

//Child component
runThisWhenParentFormSubmitted(parentForm: FormGroup) {
 parentForm.addControl('address', new FormControl(Validators.required));
 parentForm.addControl('city', new FormControl(Validators.required));
}
<!-- Parent Component -->
<form [formGroup]="parentForm" (ngSubmit)="onSubmit()">
    <app-child></app-child>
    <button type="submit">Purchase</button>
</form>
//Parent component
parentForm: FormGroup;
@ViewChild(AppChildComponent) appChildComponent: AppChildComponent;

onSubmit() {
 this.appChildComponent.runThisWhenParentFormSubmitted(this.parentForm);
}

Working Stackblitz Demo


选项 2
使用 @Input 作为可观察对象并在子组件中订阅

例子

//Parent component
parentForm: FormGroup;
parentFormSubject$ = new Subject<FormGroup>();
parentFormObservable$ = this.parentFormSubject$.asObservable();

onSubmit() {
  this.parentFormSubject$.next(this.parentForm);
}

//Make sure to complete the observable to avoid memory leaks
ngOnDestroy() {
    this.parentFormSubject$.next();
    this.parentFormSubject$.complete();
}
<!-- Parent Component -->
<form [formGroup]="parentForm" (ngSubmit)="onSubmit()">
    <app-child [form]="parentFormObservable$"></app-child>
    <button type="submit">Purchase</button>
</form>
//Child component
@Input() form: Observable<FormGroup>;
subscription: Subscription;

ngOnInit() {
  if (this.form) {
    this.subscription = this.form.subscribe(formGroup => {
      console.log("Child", formGroup);
    });
  }
}

//Make sure to unsubscribe to avoid memory leaks
ngOnDestroy() {
  if (this.subscription) {
    this.subscription.unsubscribe();
  }
}

Working Stackblitz Demo


选项 3
正如@chellappan 已经解释的那样,formGroup 不可能,因为它不包含此类事件或 属性.

您可以再创建一个 @Input 专门用于提交事件,这个解决方案有点老套

例子

//Child component
@Input() parentForm: FormGroup;

@Output() parentFormSubmittedChange = new EventEmitter<boolean>();
@Input() set parentFormSubmitted(isSubmitted: boolean) {
  if (isSubmitted) {
    console.log(this.parentForm);
    setTimeout(() => {
      this.parentFormSubmittedChange.next(false);
    });
  }
}
<!-- Parent Component -->
<form [formGroup]="parentForm" (ngSubmit)="onSubmit()">
    <app-child [parentForm]="parentForm" [(parentFormSubmitted)]="parentFormSubmitted"></app-child>
    <button type="submit">Purchase</button>
</form>
//Parent component
onSubmit() {
  this.parentFormSubmitted = true;
}

正如您在上面的子组件中看到的,我们再次使用 eventEmitterparentFormSubmitted 设置为 false。这是因为 @Input 的 setter 只会在值更改时调用。

我也将其包装在 setTimeout 中,因为它会抛出 ExpressionChangedAfterItHasBeenCheckedError 错误。

Working Stackblitz Demo

你可以在子组件中注入 FormGroupDirective 然后在子组件中订阅 ngOnSubmit 事件来监听父表单提交。

child.component.ts

 constructor(private fg: FormGroupDirective){
    this.fg.ngSubmit.subscribe(()=>{
      console.log('listen submit');
    })
  }

Working Example