如果子组件字段无效,如何禁用父组件表单提交按钮
How to disable Parent Component Form Submit button if child component fields are not valid
我正在使用模板驱动表单。
父组件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
,但它不起作用。请帮忙。
父组件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 .....
子组件 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)
}
当您使用 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);
}
}
}
然后在App-Module
中将其注册到declarations
和exports
declarations: [
RegisterTemplateFormModelDirective,
...
],
exports: [
RegisterTemplateFormModelDirective,
...
]
假设你的 <app-input-text>
是这个 HTML
代码,那么你应该像这样使用 directive
(registerChildComponentToForm
):
<input id="iban" name="iban" [(ngModel)]="bank.iban" #ibanRef="ngModel"
[required]="isMandatory" registerChildComponentToForm/>
我正在使用模板驱动表单。
父组件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
,但它不起作用。请帮忙。
父组件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 .....
子组件 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)
}
当您使用 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);
}
}
}
然后在App-Module
declarations
和exports
declarations: [
RegisterTemplateFormModelDirective,
...
],
exports: [
RegisterTemplateFormModelDirective,
...
]
假设你的 <app-input-text>
是这个 HTML
代码,那么你应该像这样使用 directive
(registerChildComponentToForm
):
<input id="iban" name="iban" [(ngModel)]="bank.iban" #ibanRef="ngModel"
[required]="isMandatory" registerChildComponentToForm/>