我有一个看起来像这样的简单表格
<form (ngSubmit)="save()" #documentEditForm="ngForm">
...
</form>
并且需要提交表单并从外部检查有效性
例如。以编程方式提交,或使用<button type="submit">
标记之外的<form>
提交。
答案 0 :(得分:62)
正确的做法实际上是
<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"
答案 1 :(得分:58)
了解如何操作:
<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
答案 2 :(得分:6)
调用<fieldType name="price" class="solr.IntPointField" sortMissingLast="true" omitNorms="true"/>
以在Caused by: java.lang.NumberFormatException: For input string: "7.5"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.parseInt(Integer.java:615)
at org.apache.solr.schema.IntPointField.createField(IntPointField.java:181)
at org.apache.solr.schema.PointField.createFields(PointField.java:216)
at org.apache.solr.update.DocumentBuilder.addField(DocumentBuilder.java:72)
at org.apache.solr.update.DocumentBuilder.toDocument(DocumentBuilder.java:179)
指令上正确设置onSubmit(undefined)
重要提示:该指令与角度形式本身不一样(更多信息见下文)
这是sourcecode for the [formGroup]
directive的一部分。 (用于反应形式)
submitted = true
您这样声明:
[formGroup]
您可以通过以下方式在 onSubmit($event: Event): boolean {
(this as{submitted: boolean}).submitted = true;
syncPendingControls(this.form, this.directives);
this.ngSubmit.emit($event);
return false;
}
文件中获得对<form [formGroup]="form" #ngForm="ngForm">
的引用:
ngForm
您可以这样使用它:
ts
示例:
@ViewChild('ngForm')
ngForm: 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);
}
}
设置。
为什么这很重要?
如果您使用任何Angular CDK或Angular Material控件,则除非触摸表单字段(单击或获得焦点)或提交整个表单,否则不会显示错误条件。
因此,如果缺少必填字段鼠标/光标从未输入,那么即使您进行this.ngForm.ngSubmit.emit()
,该字段也不会显示为红色(因为{{1 }}用于表单,而控件具有submitted = true
)。
通常,如果您有ngSubmit.emit()
(在submitted = false
标记内),它将触发标准HTML touched = false
提交(与Angular无关)-这会引发标准{{ 1}}事件在表单标签上。
如果<button type='submit'>Submit</button>
标签上还带有<form>
指令(如上所示),则该指令会“捕获” HTML表单<form>
事件,这就是导致{上面的{1}}函数被调用。
这又引发了submit
事件-如果您需要做进一步的处理,就可以抓住自己,例如显示警报。
因此,使用材质控件时,调用<form>
而不是[formGroup]
非常重要,以使验证处理正常工作。 $ event参数可以为null或未定义。
进一步阅读:查看submit
(仅适用于Angular CDK / Material)以了解确切的规则。如果解决默认值的限制变得过于复杂,则可以创建自己的
更令人困惑的是: onSubmit()
指令与仅保存数据的ngSubmit
是不同的对象。仅指令上有onSubmit
-ngSubmit.emit
上有ErrorStateMatcher
,[formGroup]
,FormGroup
之类的东西。
答案 3 :(得分:4)
如果您使用的是Reactive Forms,请使用formGroup invalid属性来禁用提交按钮:
<button
form="ngForm"
[disabled]=" editor.invalid>Enviar</button>
...
<form [formGroup]="editor" id="ngForm" (ngSubmit)="save()" novalidate >
...
</form>
答案 4 :(得分:2)
使用
对我有用的技巧是这样的:
<!-- 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>
答案 5 :(得分:2)
这对我有用。
<form #editForm="ngForm">
<button type="button" (click)="editForm.submitted = true; editForm.ngSubmit.emit(); anotherMethod();">
Submit programatically
</button>
</form>
关键是同时设置submitted = true
和发出ngSubmit
事件。
答案 6 :(得分:0)
在我的情况下,以下解决方案有效,请尝试以下简单解决方案。我不确定它是否可以在所有条件下正常工作
<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...
}
}
希望这个简单的解决方案对您有所帮助。
答案 7 :(得分:0)
此示例将在Angular 6及更高版本中工作
<form (ngSubmit)="save()" id="ngForm" [formGroup]="form">
...
</form>
<button type="submit" class="btn-save button primary" form="ngForm">Save</button>
答案 8 :(得分:0)
我写这个答案是希望它可以帮助某人。我花了一整天的时间试图解决这个问题,遵循其中的每个答案和评论......但我仍然收到错误消息,即找不到#documentEditForm(我的等价物)(无法读取未定义的属性 x ......) ,无论我尝试什么。
我之所以认为在表单标记的“外部”有问题,是因为一旦我将提交/验证按钮放在 </form>
标记内,这个问题就消失了。我去了这个兔子洞,但后来意识到我需要在表格之外的正当理由。
但后来我意识到我必须做两件事来解决这个问题,方法是 (1) 在验证时将 ?
添加到 ngForm 的名称中,以及 (2) 实现 ViewChild(NgForm) documentEditForm!: NgForm
。强>
<form #documentEditForm="ngForm">
...
</form>
<button class="btn-save button primary" (click)="save()" [disabled]="documentEditForm?.invalid">
SAVE
</button>
component.ts 内部:
import { Component, OnInit, ViewChild } from '@angular/core';
import { NgForm } from '@angular/forms';
export class XYZComponent implements OnInit {
@ViewChild(NgForm) documentEditForm!: NgForm;
...
当在 Angular 中使用模板驱动的表单时,并且您使用 #form_name="ngForm" 语法,您将其暴露给表单内部。但是,当您使用 ViewChild 时,您会将表单公开给整个组件,而不仅仅是在表单内部。请记住,如果应用无法编译或出现意外输出/错误,请尝试使用旧的 ?
。