【问题标题】:How to disable button in parent form when child form is invalid in Angular当子表单在Angular中无效时如何禁用父表单中的按钮
【发布时间】:2021-04-28 06:01:20
【问题描述】:

当嵌套子表单无效时,我想禁用父表单上的按钮。

这是父表单组件:

<hello name="{{ name }}"></hello>
<h2>Complex form with address component</h2>
<form #myForm="ngForm">
  <div>
    <label>Firstname:</label>
    <input type="text" name="firstName" ngModel>
  </div>
  <div>
    <label>Lastname:</label>
    <input type="text" name="lastName" ngModel>
  </div>
  <address></address>
</form>

<div>
  Root group valid: {{ myForm.valid }}
</div>
<br>

<!-- I want to disable this button --> 
<button [disabled]="!myForm.controls.address.valid">
  Submit Address Only
</button>

这是子地址表单组件:

import { Component } from '@angular/core';
import { ControlContainer, NgForm } from '@angular/forms';

@Component({
  selector: 'address',
  template: `
    <fieldset ngModelGroup="address" #group="ngModelGroup">
      <div>
        <label>Zip:</label>
        <input type="text" name="zip" ngModel>
      </div>
      <div>
        <label>Street:</label>
        <input type="text" name="street" ngModel>
      </div>
      <div>
        <label>City:</label>
        <input type="text" name="city" ngModel required>
      </div>
    </fieldset>
    Child group valid: {{ group.valid }}
  `,
  viewProviders: [ { provide: ControlContainer, useExisting: NgForm } ]
})
export class AddressComponent  {}

我尝试了[disabled]="!myForm.controls.address.valid",但收到一条错误消息,指出addressundefined

这是一个堆栈闪电战https://stackblitz.com/edit/angular-jmdawu?file=app%2Fapp.component.html

【问题讨论】:

    标签: angular angular-forms


    【解决方案1】:

    您可以使用事件发射器。

    子组件

    TS

    // your instance of the FormGroup
    @ViewChild('group') group: FormGroup;
    
    // emits the formGroup state to the parent
    @Output() groupIsValid: EventEmitter<boolean> = new EventEmitter<boolean>();
    
    
    ngOnInit() {
        // subscribe to the state change event and emit the current state to the parent
        this.group.statusChanges().subscribe(() => {
            this.groupIsValid.emit(this.group.valid);
        });
    }
    

    父组件

    TS

    这里我们定义了一个在事件发生时被调用的方法和一个保存状态的变量。

    // initially set to false
    childComponentIsValid: false;
    
    // gets called by event emitter
    onChildComponentEvent(value: boolean): void {
        this.childComponentIsValid = value;
    
        console.log('current child component validity state is: ' + this.childComponentIsValid);
    }
    

    HTML

    这里我们通过将参数添加到 HTML-Tag 来从子组件中获取事件

    <address (groupIsValid)="onChildComponentEvent($event)"></address>
    

    在这里你使用变量。

    <button [disabled]="!childComponentIsValid">
        Submit Address Only
    </button>
    

    就是这样。

    【讨论】:

    • 这在您需要在父子组件之间进行通信的情况下非常有用。例如,我使用您的方法禁用了按钮,但是一旦用户填写了一个表单字段,它就会启用,相反我想保持禁用它,直到填充所有表单字段。但这是一个很好的起点,谢谢!
    【解决方案2】:

    在这种情况下,“最简单的方法”是使用 ViewChild 引用孩子

    //in parent
    @ViewChild(AddressComponent) addressComponent:AdressComponent
    
    //or if you use in your .html a template reference
    // see the "#addressRef"
    // <address #addressRef></address>
    
    @ViewChild("addressRef") addressComponent:AddressComponent
    

    所以,在 parent 中你可以访问 child 中的所有变量和方法,所以你可以在 parent html 中使用

    <button [disabled]="!addressComponent.group.valid?true:null">submit</button>
    

    【讨论】:

      猜你喜欢
      • 2020-04-05
      • 2018-07-20
      • 1970-01-01
      • 1970-01-01
      • 2013-02-24
      • 1970-01-01
      • 2023-03-13
      • 2019-01-03
      • 1970-01-01
      相关资源
      最近更新 更多