Angular6 - FormControlName - TypeError: Cannot read property 'get' of undefined

Angular6 - FormControlName - TypeError: Cannot read property 'get' of undefined

我的项目中有 loginForm Stackblitz

但我在 'formControlName' 处收到错误消息:

ERROR TypeError: Cannot read property 'get' of undefined at Object.eval [as updateDirectives] (LoginComponent.html:7) at Object.debugUpdateDirectives [as updateDirectives] (core.js:23910) at checkAndUpdateView (core.js:23306) at callViewAction (core.js:23547) at execComponentViewsAction (core.js:23489) at checkAndUpdateView (core.js:23312) at callViewAction (core.js:23547) at execEmbeddedViewsAction (core.js:23510) at checkAndUpdateView (core.js:23307) at callViewAction (core.js:23547)

我的登录组件:

  initForm() {
    this.loginForm = this.fb.group({
    email: ['', Validators.required ],
    password: ['', Validators.required]     
   });
    }

我不明白错误出现在哪里。

我的输入字段组件Stackblitz

 value:string;
 onChange: ()=> void;
 onTouched: ()=> void;
 disabled:boolean;
  ngOnInit() {
   }
  writeValue(value: string): void {
  this.value = value ? value: '';  
   }
  registerOnChange(fn: any): void {
   this.onChange =fn;
   }
   registerOnTouched(fn: any): void {
   this.onTouched=fn;
   }
   setDisabledState?(isDisabled: boolean): void {
   this.disabled = isDisabled;
   } 

我错过了什么?

您可以以更简洁的方式为 return 控件编写一个小函数,这样您 html 就可以使用下面给出的示例。该错误与您尝试访问控件的方式有关。

<div class="alert alert-danger" *ngIf="email.dirty">

然后是 return 控件,以便您拥有适当的访问权限。看起来是这样。

import { AbstractControl } from '@angular/forms'; //correct type to return.


public get email(): AbstractControl
{
    return this.loginForm.controls.email
}

这将允许您访问相应表单组的控件。您可以为每个想要 access.You 的控件编写一个,也可以 return 表单,然后只访问您想要的控件。上面的代码阻止了 stackblitz 中的错误,并在屏幕上的 JSON 中显示了结果。有问题可以评论

这样做的一个好处是,在您的控制器和模板中,您可以使用它来执行快速检查。

if (this.email.valid)
{
    // any logic where you require a specific form control to be valid.
}

Documentation for Angular Forms.

参考您在 stackblitz

的代码

这是您的表格

this.loginForm = this.fb.group({
      email: ['', Validators.required ],
      password: ['', Validators.required]     
    });

并在 HTML 你错过了表单名称

<div class="form-group">
        <app-input-field formControlName="email"></app-input-field>
        <div class="alert alert-danger" *ngIf="loginForm.get('email').dirty && personalProfileForm.get('email').hasError('required')">
          email Required
        </div>
        <app-input-field formControlName="password"></app-input-field>
        <div class="alert alert-danger" *ngIf="loginForm.get('password').dirty && personalProfileForm.get('password').hasError('required')">
          password Required
        </div>
      </div>

只需在 html

中将 personalProfileForm 替换为 loginForm

此外,@dince12 的建议非常完美,可以让您的 html 代码看起来更易于阅读,干杯!

如果您想了解有关该示例的更多详细信息,可以参考以下文章: http://jasonwatmore.com/post/2018/05/10/angular-6-reactive-forms-validation-example 下面是一个小例子:

create public property like this

public get myform() { return this.myform.controls; }

and use it like this

<input type="text" formControlName="firstName" class="form-control" [ngClass]="{ 'is-invalid': submitted && myform.firstName.errors }" />
                            <div *ngIf="submitted && myform.firstName.errors" class="invalid-feedback">
                                <div *ngIf="myform.firstName.errors.required">First Name is required</div>
</div>