Angular2响应式表单ngSubmit触发时如何用Angular规范方式提交
Angular 规范下实现表单原生POST提交跳转的方案
核心逻辑:Angular 会默认拦截绑定了ngSubmit事件的表单的原生提交行为,因此需要主动触发提交,但要避免使用document.getElementById这类全局DOM查询API,使用Angular内置的视图引用机制即可完全符合框架规范。
方案1:模板传参(最简实现)
直接在模板中用模板引用变量标记表单,将引用作为参数传给提交方法,不需要在组件类中查询DOM。
模板调整代码
<form #xFormRef [formGroup]="xFormGroup" method="POST" [action]="mockUrl" (ngSubmit)="submitXForm(xFormRef)" > <input formControlName="requireSecret" type="hidden" name="requireSecret"/> <input type="submit" value="submit"/> </form>
调整点说明:
- 新增
#xFormRef模板引用变量,直接指向当前form原生元素,作用域仅在当前组件模板内,不会出现全局DOM查询的兼容问题 - 直接将表单引用作为参数传入提交方法,不需要额外查询
组件逻辑调整代码
import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; @Component({ selector: 'app-x-form', templateUrl: './x-form.component.html' }) export class XFormComponent implements OnInit { public xFormGroup: FormGroup; public mockUrl: string = "https://www.mockURL.com"; private readonly secretFormValue: string = 'secret'; constructor(private fb: FormBuilder) { } ngOnInit(): void { this.initializeForm(); } initializeForm(): void { this.xFormGroup = this.fb.group({ // 原写法缺少数组包裹,部分Angular版本下会出现值绑定失效问题 requireSecret: [this.secretFormValue] }); } public submitXForm(formElement: HTMLFormElement): void { // 可在此处添加自定义校验、参数处理等前置逻辑 if (this.xFormGroup.invalid) return; console.log("clicked"); formElement.submit(); } }
方案2:ViewChild 视图查询(无需模板传参)
如果不想在模板方法中传参,可以用Angular官方提供的@ViewChild装饰器直接获取模板内的元素引用。
模板代码
<form #xFormRef [formGroup]="xFormGroup" method="POST" [action]="mockUrl" (ngSubmit)="submitXForm()" > <input formControlName="requireSecret" type="hidden" name="requireSecret"/> <input type="submit" value="submit"/> </form>
组件逻辑调整
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; @Component({ selector: 'app-x-form', templateUrl: './x-form.component.html' }) export class XFormComponent implements OnInit { @ViewChild('xFormRef') xFormRef!: ElementRef<HTMLFormElement>; public xFormGroup: FormGroup; public mockUrl: string = "https://www.mockURL.com"; private readonly secretFormValue: string = 'secret'; constructor(private fb: FormBuilder) { } ngOnInit(): void { this.initializeForm(); } initializeForm(): void { this.xFormGroup = this.fb.group({ requireSecret: [this.secretFormValue] }); } public submitXForm(): void { if (this.xFormGroup.invalid) return; console.log("clicked"); this.xFormRef.nativeElement.submit(); } }
最简无代码方案
如果提交前不需要执行任何自定义校验、逻辑处理,可以直接删除(ngSubmit)绑定和组件内对应的提交方法:
<form [formGroup]="xFormGroup" method="POST" [action]="mockUrl" > <input formControlName="requireSecret" type="hidden" name="requireSecret"/> <input type="submit" value="submit"/> </form>
对于没有绑定
ngSubmit事件的表单,Angular不会拦截其原生提交行为,点击提交按钮会自动以POST方式跳转到mockUrl,不需要写任何提交触发代码。
注意事项
- 禁止使用
document.getElementById这类全局DOM操作,在Angular SSR服务端渲染、Shadow DOM组件封装场景下会直接失效,模板引用变量是框架官方推荐的DOM访问方式 - 响应式表单初始化时,
FormBuilder.group的控件默认值需要用数组包裹,直接传值在部分Angular版本下会出现值不更新的问题
内容的提问来源于stack exchange,提问作者Jonas Chan
相关产品推荐
相关产品推荐

