【问题标题】:Unable to assign form control to template variable in Reactive Forms - angular?无法将表单控件分配给反应式表单中的模板变量 - 角度?
【发布时间】:2017-09-09 04:40:54
【问题描述】:

我是 Angular 的新手,可以说,我有响应式的形式,比如 follow

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

我的角度模板看起来像跟随

<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')">

这样我就可以使用 like

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

  </div>

但是我遇到了类似的错误

compiler.es5.js:1690 未捕获错误:模板解析错误: 没有将“exportAs”设置为“registerFormGroup.get('email')”的指令(“l> ]#emailForm="registerFormGroup.get('email')">

我犯了什么错误??

【问题讨论】:

标签: javascript angular angular4-forms


【解决方案1】:

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

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>

【讨论】:

  • 如何提高性能?这难道不会适得其反吗?
【解决方案2】:

在组件上创建一个方法,如果表单有效则返回,并在组件中返回

  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>

【讨论】:

    【解决方案3】:

    试试这个:

    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])]
            });
    }
    }
    

    【讨论】:

      【解决方案4】:

      由于更改检测策略,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 功能,但为了答案的完整性,我发布了这个答案。

      【讨论】:

        【解决方案5】:

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

        诀窍是从您的组件中公开 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; }
        

        【讨论】:

          【解决方案6】:

          我也在寻找比多次调用 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 功能创建模板变量

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-07-31
            • 1970-01-01
            • 2021-08-26
            • 2019-02-04
            • 2023-03-20
            • 1970-01-01
            • 2012-08-07
            • 2020-05-05
            相关资源
            最近更新 更多