【问题标题】:Can't acces FormControl instance directly. Cannot read property 'invalid' of undefined无法直接访问 FormControl 实例。无法读取未定义的属性“无效”
【发布时间】:2017-11-19 05:47:04
【问题描述】:

无法以与 Angular 文档中相同的方式访问它,因此必须先获取 FormGroup 实例并在其中找到 FormControl 实例。我想知道为什么?这个例子有效:

<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
  <div class="form-group">
    <label for="username">Username</label>
    <input 
      type="text"
      name="username"
      class="form-control"
      formControlName="username"
    >
    <div *ngIf="myForm.controls.username.invalid" class="alert alert-danger">
      username is required
    </div>
  </div>

虽然这会引发错误(它们之间的区别仅在 *ngIf 语句中):

<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
  <div class="form-group">
    <label for="username">Username</label>
    <input 
      type="text"
      name="username"
      class="form-control"
      formControlName="username"
    >
    <div *ngIf="username.invalid" class="alert alert-danger">
      username is required
    </div>
  </div>

无法读取未定义的“无效”属性

form.component:

import {Component} from '@angular/core';
import {FormGroup, FormControl, Validators} from '@angular/forms';

@Component({
  selector: 'sign-up',
  templateUrl: 'app/sign-up.component.html'
})

export class SignUpComponent {

  myForm = new FormGroup({
    username: new FormControl('username', Validators.required),
    password: new FormControl('', Validators.required),
  });
}

【问题讨论】:

    标签: angular angular2-forms angular-reactive-forms


    【解决方案1】:

    它会引发错误,因为您没有名为 usernamepassword 的变量。

    为了解决这个问题,您可以:

    1. 将控件存储在组件变量中:

    TS

    @Component({
      changeDetection: ChangeDetectionStrategy.OnPush,
      selector: 'my-app',
      templateUrl: './app.component.html',
      styleUrls: [ './app.component.css' ]
    })
    export class AppComponent {
      readonly usernameCtrl = this.formBuilder.control('username', Validators.required);
      readonly passwordCtrl = this.formBuilder.control('', Validators.required);
      readonly formGroup = this.formBuilder.group({
        username: this.usernameCtrl,
        password: this.passwordCtrl
      });
    

    HTML

    <div 
      *ngIf="userNameCtrl.invalid" class="alert alert-danger"
    >
      username is required
    </div>
    
    1. 使用AbstractControl#get获取控制权:

    HTML

    <div 
      *ngIf="formGroup.get('username').invalid" class="alert alert-danger"
    >
      username is required
    </div>
    
    1. 使用AbstractControl#hasError,这样您就可以为每个现有的验证指定不同的消息:

    HTML

    <div 
      *ngIf="formGroup.hasError('required', 'username')" class="alert alert-danger"
    >
      username is required
    </div>
    

    DEMO

    【讨论】:

    • 好的...我期待一些更简单的东西..这是否意味着文档中的示例是错误的...? angular.io/api/forms/FormGroupDirective
    • @FromZeroToHero 不,文档是正确的。有一个名为 firstget 方法返回 FormControl first
    【解决方案2】:

    实际上我只是 Angular 的新手,我才用了一个月,还在寻找一些答案,呵呵,但是在你的组件中添加一个像这样的 getter:

    export class SignUpComponent {
    
     myForm = new FormGroup({
        username: new FormControl('', Validators.required),
        password: new FormControl('', Validators.required),
      });
    
    get username(){
      return this.myForm.controls['username'];
    }
    
    }
    

    【讨论】:

      【解决方案3】:

      在ts文件中添加:

      get username() { return this.myForm.get('username'); }
      get password() { return this.myForm.get('password'); } }
      

      【讨论】:

        【解决方案4】:

        我遇到了同样的问题,我在“myForm.controls....”中添加了“this”。它帮助了我。

        代替:

        <div *ngIf="myForm.controls.username.invalid" class="alert alert-danger">
              username is required
         </div>
        

        做:

         <div *ngIf="this.myForm.controls.username.invalid" class="alert alert-danger">
              username is required
         </div>
        

        希望这对您有所帮助。

        【讨论】:

          【解决方案5】:

          对我有用:

          form.component:

          getFormControl(name) {
              return this.Form.get(name);
          }
          

          模板:

          <input 
            type="text"
            name="username"
            class="form-control"
            formControlName="username"
          >
          <div *ngIf="getFormControl('username').invalid" class="alert alert-danger">
            username is required
          </div>
          

          【讨论】:

            【解决方案6】:

            您可以使用表单组并在控制器中定义相应的 getter 来解决此问题。为了实现这个目标:

            在控制器中:

            1) 去掉表单控制变量的定义和初始化

            usernameCtrl: FormControl;
            passwordCtrl: FormControl;
            ...
            this.usernameCtrl = this.formBuilder.control('username',Validators.required);
            this.passwordCtrl = this.formBuilder.control('', Validators.required);
            

            2)将表单组初始化改成这个

            ngOnInit() {
            this.myForm = this.formBuilder.group({
              username: ['usename', Validators.required]
              password: ['', Validators.required]
            });
            

            }

            3) 添加吸气剂

            get username() { return this.myForm.get('username'); }
            get password() { return this.myForm.get('password'); }
            

            在模板中:

            1) 添加带有 [formGroup]="MyForm" 的父 div

            <div [formGroup]="myForm">
            ...
            </div>
            

            2) 将 [formControl]="usernameCtrl" 更改为 forcontrolName=username 和 *ngIf="usernameCtrl.invalid" 更改为 *ngIf="username.invalid"

            <input type="text"
                   name="username"
                   class="form-control"
                   formControlName="username">
              <div *ngIf="username.invalid" class="alert alert-danger"> 
                username is required
              </div>
            

            3) 更改 [formControl]="passwordCtrl" 为 forcontrolName=password 和 *ngIf="passwordCtrl.invalid" 为 *ngIf="password.invalid" 。

            <input type="text"
                   name="password"
                   class="form-control"
                   formControlName="password">
              <div *ngIf="password.invalid" class="alert alert-danger">
                password is required
              </div>
            

            Plunker

            【讨论】:

              猜你喜欢
              • 2023-03-20
              • 2018-04-23
              • 1970-01-01
              • 2021-11-01
              • 1970-01-01
              • 2018-02-16
              • 1970-01-01
              • 1970-01-01
              • 2019-05-21
              相关资源
              最近更新 更多