如果子组件字段无效,如何禁用父组件表单提交按钮
Posted
技术标签:
【中文标题】如果子组件字段无效,如何禁用父组件表单提交按钮【英文标题】:How to disable Parent Component Form Submit button if child component fields are not valid 【发布时间】:2019-01-03 03:39:33 【问题描述】:我正在使用模板驱动表单。
父组件 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 中你没有访问 sharedVarChange no? 没有。我现在正在尝试 您可以在父母和孩子之间共享相同的form
。 ***.com/questions/51281527/… 唯一的区别是您有模板驱动的表单。这不应该是一个问题。完成后,您可以获取表单控件以在任一组件中进行验证
【参考方案1】:
父组件 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 .....
【讨论】:
【参考方案2】:子组件 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)
【讨论】:
【参考方案3】:当您使用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/>
【讨论】:
非常感谢。这个解决方案效果很好。只有1个问题。我在控制台中收到以下错误。你能帮忙吗? ExpressionChangedAfterItHasBeenCheckedError:表达式在检查后已更改。以前的值:'ng-valid: true'。当前值:'ng-valid: false'。 我已经用setTimeOut
修复了它,但我认为它不是正确的方法:setTimeout(() => if (this.form && this.eltControl) this.form.form. addControl(this.eltControl.name, this.eltControl.control); , 1);
setTimeOut
的方法也是正确的。我也用它。或者使用 Angular 的 ChangeDetectorRef
的方法 angular.io/api/core/ChangeDetectorRef以上是关于如果子组件字段无效,如何禁用父组件表单提交按钮的主要内容,如果未能解决你的问题,请参考以下文章
父组件中的 Reactjs 按钮,在子组件中提交 Redux 表单