Angular 2模板驱动表单:在组件中访问ngForm

48

我想在Angular 2中使用模板驱动表单,并且我需要在我的指令中访问当前ngForm,作为本地属性,而不想将它们作为参数传递。

我的表单如下所示:

<form #frm="ngForm" (ngSubmit)="save(frm)">
    <input [(ngModel)]="user.name" #name="ngForm" type="text">
    <a (click)="showFrm()" class="btn btn-default">Show Frm</a>
</form>

并且在我的组件中

@Component({
    selector: 'addUser',
    templateUrl: `Templates/AddUser`,
})

export class AddUserComponent implements CanDeactivate {
    public user: User;
    // how can I use this without defining the whole form 
    // in my component I only want to use ngModel
    public frm : ngForm | ControlGroup;

    public showFrm()  : void{
        //logs undefined on the console
        console.log(this.frm);
    }
}

这可行吗,因为我需要在一个函数中检查myFrm是否有效或已被触摸,而我无法将当前表单作为参数传递,例如“routerCanDeactivate”,我也不想使用模型驱动的表单,因为这样写的代码太多了,我喜欢老派的ng1模型绑定。

我已更新我的示例,但组件中不知道frm。


我在 Github 上创建了一个功能请求:https://github.com/angular/angular/issues/8538 - squadwuschel
AddUserComponent 应该作为表单的子元素放置在内部吗?
...
- Felix
2个回答

97
您需要将ngControl属性添加到您想要进行检查的输入框中。
<form #frm="ngForm" (ngSubmit)="save(frm)">
   <input [(ngModel)]="user.name" #name="ngForm" ngControl="name"  type="text">
   <a (click)="showFrm()">Show Frm</a>
</form>

在组件中,您可以使用以下方式访问“frm”变量:

import {Component, ViewChild} from 'angular2/core';
...
@ViewChild('frm') public userFrm: NgForm;
...
public showFrm(): void{
    console.log(this.userFrm);
}

您无法在构造函数中访问frm,因为此时它不存在,但是在ngAfterViewInit中可以访问它。

自Angular 8以来,他们已经更新了ViewChild的参数。目前我需要使用以下语法:

@ViewChild('frm', { static: true })userFrm: NgForm;

@squadwuschel 我尝试访问组件中的表单控件,以便在每个控件上调用setErrors()。因此,当我使用console.log(this.frm.controls)记录日志时,我可以在浏览器控制台中看到键值对,但是当我尝试使用for-in循环迭代this.frm.controls或尝试使用Object.keys(this.frm.controls)获取键数组时,它返回空数组。您有遇到过这样的问题吗?任何提示或建议将不胜感激。 - Tanya Petkova
1
input 元素上使用 #name="ngForm" 是有效的吗? - Felix
3
你的例子中有一个小错误 - 应该是 console.log(this.userFrm) 而不是 console.log(this.fmr) - simbro

-1
<h1>Login</h1>
<hr />
<div class="col-md-4">
  <form autocomplete="off" #loginForm="ngForm" (ngSubmit)="login(loginForm.value)">
    <div class="form-group">
      <em *ngIf="loginForm.controls.userName?.invalid">required</em>
      <label for="userName">User Name:</label>
      <input
        id="userName"
        (ngModel)="(userName)"
        name="userName"
        type="text"
        class="form-control"
        placeholder="User Name..."
      />
    </div>
    <div class="form-group">
      <em *ngIf="loginForm.controls.password?.invalid">required</em>
      <label for="password">Password:</label>
      <input
        id="password"
        (ngModel)="(password)"
        name="password"
        type="password"
        class="form-control"
        placeholder="Password..."
      />
    </div>

    <button type="submit" [disabled="loginForm.invalid" ]class="btn btn-primary">Login</button>
    <button type="button" class="btn btn-default">Cancel</button>
  </form>
</div>

import { Component } from '@angular/core';
import { AuthService } from './auth.service';

@Component({
  selector: 'login',
  templateUrl: './app/login/login.component.html'
})
export class LoginComponent {
  constructor(private authService: AuthService) {}

  login(formValues) {
    this.authService.loginUser(formValues.userName, formValues.password);
  }
}

4
虽然这段代码可能回答了问题,但如果提供关于为什么以及/或者如何回答问题的额外背景信息,可以提高其长期价值。 - Donald Duck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接