代码之家  ›  专栏  ›  技术社区  ›  Adrita Sharma

如果子组件字段无效,如何禁用父组件表单提交按钮

  •  0
  • Adrita Sharma  · 技术社区  · 6 年前

    我正在使用模板驱动的表单。

    父组件HTML

    <form #BasicForm="ngForm" (ngSubmit)="onBasicDetailsSubmit()" id="BasicForm">
    
      <app-input-text [(sharedVar)]="dashboardDetails.Text1" [isMandatory]="true" ></app-input-text>
      <app-input-text [(sharedVar)]="dashboardDetails.Text2" [isMandatory]="false"></app-input-text>
    
      <input type="submit" value="Save" [disabled]="!BasicForm.valid" class="btn btn-success">
    
    </form>
    

    子组件

    TS

    @Input() sharedVar: number;
    @Input() isMandatory: boolean;
    
    @Output() sharedVarChange = new EventEmitter();
    
    
    change(newValue) {
      this.sharedVar = newValue;
      this.sharedVarChange.emit(newValue);
    }
    

    HTML

    <input type="text" class="form-control" [(ngModel)]="sharedVar" (ngModelChange)="change($event)" [attr.required]="isMandatory">
    

    提交按钮未被禁用。我试过写作 required 在子组件和父组件选择器中,但它不起作用。请帮忙。

    3 回复  |  直到 6 年前
        1
  •  1
  •   Manu    6 年前

    当你使用 Template-Driven-Form ,验证的最佳方法 Child components 是创建一个 custom-Directive 这样,您将始终在子组件表单中添加要验证的每个字段:

    您可以使用这个:

    import {Directive, OnInit} from '@angular/core';
    import {NgControl, NgForm, NgModel} from "@angular/forms";
    
    /**
     * This attribute directive must be used to each input-field of a childComponent.
     * That input-field must contain a NgModel attribute, else the application must throw an error
     * Usage: (<input class="form-control" type="text" registerChildComponentToForm
     *          [(ngModel)]="testname" name="testname" required />
     */
    
    @Directive({
        selector: '[registerChildComponentToForm]',
        providers: [NgModel]
    })
    export class RegisterTemplateFormModelDirective implements OnInit {
    
        constructor(private form: NgForm, private eltControl: NgControl) {
        }
    
        ngOnInit() {
            if (this.form && this.eltControl) {
                this.form.form.addControl(this.eltControl.name, this.eltControl.control);
            }
        }
    
    }

    然后注册到 declarations exports 在你 App-Module

    declarations: [
            RegisterTemplateFormModelDirective,
            ...
    ],
    exports: [
            RegisterTemplateFormModelDirective,
            ...
    ]

    假设你的 <app-input-text> 这是 HTML 代码,那么您应该只使用 directive ( registerChildComponentToForm 像这样:

    <input id="iban" name="iban" [(ngModel)]="bank.iban" #ibanRef="ngModel" 
      [required]="isMandatory" registerChildComponentToForm/>
        2
  •  0
  •   Malindu Sandaruwan    6 年前

    父组件HTML

    <app-input-text [(sharedVar)]="dashboardDetails.Text1" (sharedVarChange)="sharedVarChangeHandle($event)" ...
    

    父组件ts

    sharedVarChangeHandle($event) {
        // by evaluating the value passed you can update a variable (ex: disableSubmit)
    } 
    

    父组件HTML

    <input type="submit" value="Save" [disabled]="!disableSubmit" class="bt .....
    
        3
  •  0
  •   Malindu Sandaruwan    6 年前

    子组件ts

    valid // this is a public variable
    
    change(newValue) {
      this.sharedVar = newValue;
      this.sharedVarChange.emit(newValue);
      // here conditioanally update the **valid** variable (true or false)
    }