无法将表单控件分配给 Reactive Forms 中的模板变量 - angular?

Unable to assign form control to template variable in Reactive Forms - angular?

我是 angular 的新手,可以说,我的反应形式如下

ngOnInit() {
this.registerFormGroup = this.formBuilder.group({
    email: [ '', Validators.compose([Validators.required, Validators.email])],
    password: this.formBuilder.group({
    first: [ '', Validators.required ],
    second: [ '', Validators.required,  ] 
    })
  });
}

我的 angular 模板看起来像

<div class="container">
  <form [formGroup]="registerFormGroup" 
    (ngFormSubmit)="registerUser(registerFormGroup.value)" novalidate>
<div class="form-group" >
    <label for="email">Email</label>
    <input type="email" formControlName="email" placeholder="Enter Email" 
   class="form-control">
</div>
<div *ngIf="!registerFormGroup.get('password').get('first').valid" 
     class="alert alert-danger">

</div>

<div class="form-group text-center">
  <button type="submit" class="btn btn-success btn-lg" 
  [disabled]="!registerFormGroup.valid">Submit</button>
</div>

例如,电子邮件字段有两个验证,例如 requiredemail 类型验证所以取决于错误我必须显示错误消息所以在我的模板中使用像

<div *ngIf="!registerFormGroup.get('email').valid && (registerFormGroup.get('email').touched)" 
  class="alert alert-danger">

  </div>

我没有一次又一次地添加相同的 registerFormGroup.get('email'),而是尝试在

中创建类似 #emailForm="registerFormGroup.get('email')" 的模板表达式
<input type="email" formControlName="email" placeholder="Enter Email" class="form-control" #emailForm="registerFormGroup.get('email')">

这样我就可以使用

<div *ngIf="!emailForm.valid" class="alert alert-danger">

  </div>

但我收到类似

的错误

compiler.es5.js:1690 Uncaught Error: Template parse errors: There is no directive with "exportAs" set to "registerFormGroup.get('email')" ("l> ]#emailForm="registerFormGroup.get('email')">

我犯了什么错误??

试试这个:

component.html

<div class="container">
    <form [formGroup]="registerFormGroup" 
    (ngFormSubmit)="registerUser(registerFormGroup.value)" novalidate>
    <div class="form-group" [ngClass]="{'has-error':!registerFormGroup.controls['email'].valid}">
        <label for="email">Email</label>
        <input type="email" formControlName="email" placeholder="Enter Email" 
        class="form-control">
        <p class="alert alert-danger" *ngIf="registerFormGroup.controls['email'].dirty && !registerFormGroup.controls['email'].valid">Invalid email address</p>
    </div>
    <div class="form-group text-center">
        <button type="submit" class="btn btn-primary" [disabled]="!registerFormGroup.valid">Submit</button>
    </div>
</form>
</div>

component.ts

import { FormGroup, FormBuilder, Validators } from '@angular/forms';

export class AppComponent implements OnInit {
registerFormGroup: any;
constructor(
        private formBuilder: FormBuilder
    ) {}

ngOnInit() {
this.registerFormGroup = this.formBuilder.group({
            email: [null , Validators.compose([Validators.required, Validators.email])]
        });
}
}

在组件上创建一个方法,return判断表单是否有效,return它在组件中

  checkError(){ // either you can pass the form from the template or use the component for decleration
    return registerFormGroup.get('email').valid;
  }

在模板调用中

  <div *ngIf="checkError()" class="alert alert-danger">
    // Always make sure not to use controls in the template it will result in AOT compilation error
  </div>

您可以创建常用函数来访问如下表单:

validateFormControl(controName: string) {
    let control = registerFormGroup.get(controName);
    return control.invalid && control.touched;
}

在Templete中任何需要的地方都可以使用这个调用,你只需要在函数中传递你的控件名称,你也可以根据需要修改这个函数,你不需要使用form.get所有的时间。这使您的模板更简洁,性能更高效。

<div *ngIf="validateFormControl('email')" 
  class="alert alert-danger">
  error message
</div>

<div *ngIf="validateFormControl('password')" 
      class="alert alert-danger">
   error message
</div>
由于更改检测策略,

Angular 团队强烈反对在模板中使用函数输出。您可能对以下解决方案感兴趣,使用 ngForm 指令:

<div class="container">
  <form [formGroup]="registerFormGroup" 
    (ngFormSubmit)="registerUser(registerFormGroup.value)" novalidate>
<div class="form-group" >
    <label for="email">Email</label>
    <input type="email" formControlName="email" placeholder="Enter Email " 
   class="form-control" #email="ngForm">
</div>
<div *ngIf="email.invalid" 
     class="alert alert-danger">

</div>

将它复制粘贴到模板中仍然是一个秘密,但至少您可以通过它的模板变量直接引用控件。我个人仍然使用控制器 getter 功能,但为了答案的完整性,我发布了这个答案。

虽然我同意接受的答案(你应该在你的表单组件中有一个专用的方法来封装验证过程) 有时您需要快速检查模板:

诀窍是从您的组件中公开 formGroup 并像这样使用它:
模板:

<input id="name" class="form-control"
     formControlName="name" required
     [class.is-invalid]="
     f.name.invalid &&
     (f.name.touched ||
     f.name.touched.dirty)">


分量:

  //easily access your form fields
  get f() { return this.checkoutForm.controls; }

我也在寻找比多次调用 form.get 更优雅的解决方案。这是我使用 ngif

得出的结果
 <div class="col-sm-6" *ngIf="form.get('sponsor') as sponsor">

            <input type="text" formControlName="sponsor" id="sponsor" class="form-control" name="sponsor"
              [class.is-invalid]="sponsor.errors && sponsor.touched">

        </div>

使用 ngIf 的 as 特性创建模板变量