我有一个看起来像这样的简单形式
<form (ngSubmit)="save()" #documentEditForm="ngForm">
...
</form>
并且需要提交表格并从外部检查其有效性
例如。要么以编程方式提交,要么使用<button type="submit">
标记之外的<form>
。
实际上,正确的做法是
<form (ngSubmit)="save()" id="ngForm" #documentEditForm="ngForm">
...
</form>
<button class="btn-save button primary" form="ngForm" [disabled]="!documentEditForm.form.valid">
SAVE
</button>
表单需要有一个ID id="example-form"
和提交按钮在form="example-form"
中匹配的ID
找到了怎么做:
<formname>.ngSubmit.emit()
<formname>.form.valid
获取表单状态例:
<form (ngSubmit)="save()" #documentEditForm="ngForm">
...
</form>
<button class="btn-save button primary"
(click)="documentEditForm.ngSubmit.emit()"
[disabled]="!documentEditForm.form.valid">SAVE</button>
编辑:正如@ yuriy-yakovenko指出的那样,您应该在组件代码中添加以下内容:
@ViewChild('documentEditForm') documentEditForm: FormGroupDirective;
如果还没有,请不要忘记导入FormGroupDirective
调用onSubmit(undefined)
在submitted = true
指令上正确设置[formGroup]
注意:该指令与角形式本身不是同一个对象(更多内容如下)
这是sourcecode for the [formGroup]
directive的一部分。 (对于反应形式)
@Directive({
selector: '[formGroup]',
providers: [formDirectiveProvider],
host: {'(submit)': 'onSubmit($event)', '(reset)': 'onReset()'},
exportAs: 'ngForm'
})
export class FormGroupDirective extends ControlContainer implements Form,
OnChanges {
/**
* @description
* Reports whether the form submission has been triggered.
*/
public readonly submitted: boolean = false;
.....
onSubmit($event: Event): boolean {
(this as{submitted: boolean}).submitted = true;
syncPendingControls(this.form, this.directives);
this.ngSubmit.emit($event);
return false;
}
你这样使用它:
<form [formGroup]="form" #formRef="ngForm">
您可以在FormGroupDirective
文件中获取对ts
的引用:
@ViewChild('formRef')
formRef: FormGroupDirective;
NgForm
是在创建<form>
标记时自动应用的另一个指令。NgForm
和FormGroupDirective
的源代码中都有exportAs: 'ngForm'
(并且它们都声明了submitted
和ngSubmit
属性)。但当我把#ngForm='ngForm'
我得到一个FormGroupDirective
类型的对象而不是NgForm
(在调试器中验证)。我不确定为什么 - 但这就是为什么我宣布它为FormGroupDirective
而不是NgForm
- 我想也许是第一次获胜。你这样使用它:
this.formRef.onSubmit(undefined)
例:
// html
<form [formGroup]="form" #formRef="ngForm">
// ...Form Controls
</form>
// component.ts
export class MyComponent {
@ViewChild('formRef')
formRef: FormGroupDirective;
form: FormGroup = new FormGroup({
myInput: new FormControl(''),
//etc...
});
submitFormProgrammatically() {
this.formRef.onSubmit(undefined);
}
}
如果你只是打电话给this.formRef.ngSubmit.emit()
,因为其他一些答案建议你不会得到所有重要的submitted = true
设置。
为什么这很重要?
如果您正在使用任何Angular CDK或Angular Material控件,则不会显示错误条件,除非已触摸表单字段(单击或获得焦点)或已提交整个表单。
因此,如果您有一个缺少必需字段,鼠标/光标从未输入过,那么即使您执行ngSubmit.emit()
,该字段也不会显示为红色(因为表单和控件的submitted = false
具有touched = false
)。
通常,如果你有<button type='submit'>Submit</button>
(在<form>
标签内),它将触发标准HTML <form>
提交(与Angular无关) - 并在表单标签上引发标准的submit
事件。
如果<form>
标签上还有一个[formGroup]
指令(如上所示)那么HTML表单submit
事件被指令“捕获”,这就是导致上面的onSubmit()
函数被调用的原因。
这反过来引发了ngSubmit
事件 - 如果你需要进行进一步的处理,你可以自己捕捉 - 比如显示警报。
所以调用onSubmit
非常重要,而不是ngSubmit.emit
to在使用材质控件时可以使验证处理工作。 $ event参数可以为null或undefined。
进一步阅读:查看ErrorStateMatcher
(仅适用于Angular CDK / Material)以查看确切的规则。如果解决默认的限制变得过于复杂,您可以创建自己的。
更令人困惑的是:[formGroup]
指令与FormGroup
不同,它只保存数据。只有指令上有submitted
- 而FormGroup
有像touched
,pristine
,dirty
这样的东西。
如果您使用的是Reactive Forms,请使用formGroup invalid属性来禁用提交按钮:
<button
form="ngForm"
[disabled]=" editor.invalid>Enviar</button>
...
<form [formGroup]="editor" id="ngForm" (ngSubmit)="save()" novalidate >
...
</form>
一个适合我使用的技巧
是这样的:
<!-- real button will simulate click on invisible button (cf. form) -->
<button onclick="document.getElementById('hiddenSaveButtonForMicrosoftWithLove').click()">
The Real Button outside forms
</button>
<form>
<!-- will be called in the background and is never visible -->
<button id="hiddenSaveButtonForMicrosoftWithLove" type="submit" style="display: none;">hiddenSaveButtonForMicrosoftWithLove</button>
</form>
以下解决方案适用于我的情况,请尝试这个简单的解决方案。我不确定,它是否适用于所有条件:
<form #documentEditForm="ngForm" id="ngForm" (ngSubmit)="save(documentEditForm.valid)">
...Your Input Elements...
</form>
该按钮应该在表单之外声明如下:
<button form="ngForm">Submit</button>
表单的验证应通过以下条件检查save()
save(isValid:boolean){
if(isValid) {
...Your code to save details...
}
}
希望这个简单的解决方案能帮到你。
此示例适用于Angular 6及更高版本
<form (ngSubmit)="save()" id="ngForm" [formGroup]="form">
...
</form>
<button type="submit" class="btn-save button primary" form="ngForm">Save</button>