Angular 6:类型错误:无法读取未定义的属性“invalid”?

6

我正在编写应用程序的前端,但是在我的Angular 6注册代码中遇到了一个问题。我似乎产生了TypeError,但我不知道为什么会是未定义的。

这是我的registration.component.ts文件。

import { Component, OnInit } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule} from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';
import {RouterModule} from '@angular/router';
import {Routes} from '@angular/router';
import {
  MatToolbarModule, MatButtonModule, MatInputModule, MatIconModule, MatSelectModule, MatTableModule, MatGridListModule,
  MatCardModule, MatMenuModule, MatFormFieldModule, MatOptionModule, MatRadioModule
} from '@angular/material';
import {HttpClientModule } from '@angular/common/http';
import {FormBuilder, FormControl, FormsModule} from '@angular/forms';
import {FormGroup} from '@angular/forms';
import {Validators} from '@angular/forms';
import {ReactiveFormsModule} from '@angular/forms';
import { LayoutModule } from '@angular/cdk/layout';
import 'hammerjs';


@Component({
  selector: 'app-register',
  templateUrl: './register.component.html',
  styleUrls: ['./register.component.css']
})
export class RegisterComponent implements OnInit {
  registerForm: FormGroup;
  loading = false;
  submitted = false;
  hide = true;
  public lastNameC: FormControl;
  public firstNameC: FormControl;
  public emailC:  FormControl;
  public passwordC: FormControl;
  handleSubmit() {
    console.log(this.registerForm.value);
    alert('You registered!');
  }

  trueOrFalse() {
    return this.registerForm.valid;
  }

  passwordError() {
    return this.passwordC.hasError('minlength') ? 'Your password is too short.' :
      this.passwordC.hasError('pattern') ? 'Your password must have one uppercase letter, one lowercase letter, one number and one non alphanumeric character.' :
        ' ';
  }

  lastNameError() {
    if (this.lastNameC.hasError('required')) {
      return 'Last name is required.';
    }
  }

  emailError() {
    return this.emailC.hasError('required') ? 'You must enter a value.' :
      this.emailC.hasError('email') ? 'Not a valid email. Please read the field again.' :
        ' ';
  }

  firstNameError() {
  if (this.firstNameC.hasError('required')) {
    return 'Enter your first name.';
  }



  }



  constructor() {

  }

  ngOnInit() {
    this.registerForm = new FormGroup({
      emailC: new FormControl('', [Validators.required, Validators.email]),
      firstNameC : new FormControl('', [Validators.required]),
      lastNameC: new FormControl('', [Validators.required]),
      passwordC : new FormControl('', [Validators.required, Validators.minLength(8), Validators.pattern('^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[$@$!%*?&])[A-Za-z\\d$@$!%*?&]{8,}')]),
    });


  }


}

<form class="example-form" [formGroup]="registerForm" (ngSubmit)="handleSubmit()">
  <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
  <mat-form-field class="example-full-width">
  <input matInput placeholder="First Name"  formControlName="firstNameC">
    <mat-error *ngIf="firstNameC.invalid">{{firstNameError()}}</mat-error>
 </mat-form-field>
  <mat-form-field class="example-full-width">
    <input matInput placeholder="Last Name" formControlName="lastNameC">
    <mat-error *ngIf="lastNameC.invalid"> {{lastNameError()}} </mat-error>
  </mat-form-field>
  <mat-form-field class="example-full-width">
    <input  matInput placeholder="email" formControlName="emailC">
    <mat-error *ngIf="emailC.invalid">{{emailError()}}</mat-error>
  </mat-form-field>
  <mat-form-field>
    <input matInput placeholder="password" formControlName="passwordC">
    <mat-error *ngIf="passwordC.invalid">{{passwordError()}}</mat-error>
  </mat-form-field>

  <button mat-raised-button color="accent"> Register </button>

</form>

这是我的注册表单的html。错误出现在第4行,但我已经引用了适当的控件来进行formControlName。

The error aforementioned..
RegisterComponent.html:4 ERROR TypeError: Cannot read property 'invalid' of undefined
    at Object.eval [as updateDirectives] (RegisterComponent.html:5)
    at Object.debugUpdateDirectives [as updateDirectives] (core.js:11062)
    at checkAndUpdateView (core.js:10459)
    at callViewAction (core.js:10700)
    at execComponentViewsAction (core.js:10642)
    at checkAndUpdateView (core.js:10465)
    at callViewAction (core.js:10700)
    at execEmbeddedViewsAction (core.js:10663)
    at checkAndUpdateView (core.js:10460)
    at callViewAction (core.js:10700)

这是我的StackBlitz示例,出现了错误。
2个回答

10
你需要使用安全导航操作符,如下所示:
   <mat-error *ngIf="firstNameC?.invalid">{{firstNameError()}}</mat-error>

STACKBLITZ DEMO


1
嗨,@Sajeetharan,你能解释一下什么是安全导航运算符吗?作为一个前端新手,我从未见过这种安全导航运算符。另外,为什么没有出现错误消息呢? - Melcalc
https://dev59.com/aFUK5IYBdhLWcg3wlQsJ#51615259 - Sajeetharan
如果名字未定义,它会检查名字并抛出错误,标记是否有帮助。 - Sajeetharan
嗨,为什么emailC或者firstNameC在一开始会是未定义的呢?谢谢,并且我已经标记了你的答案。 - Melcalc
@Melcalc 在 ngOnInit 运行之前,emailC 和 firstNameC 都是未定义的。 - olefrank

-1
<form action="#" #f="ngForm" (ngSubmit)="f.form.valid && onSubmit()">
    <div class="form-group" [class.has-error]="firstName.invalid && firstName.touched">
            <label  class="control-label">Full Name : </label>
            <input type="text" name="uname"  [(ngModel)]="uname" class="form-control" #firstName="ngModel">
            <span class="help-block" *ngIf="firstName.touched && firstName.invalid">Full Name is requried</span>
            {{firstName.touched}}
            {{firstName.invalid}}

    </div>
    <div class="form-group">
            <label  class="control-label">Password : </label>
            <input type="password" name="upass" class="form-control" [(ngModel)]="upass" #Pass="ngModel">
            <span class="help-block" *ngIf="Pass.invalid">Full Name is requried</span>
    </div>
    <div class="form-group">
            <input type="submit" value="submit" class="btn btn-primary">
    </div>
</form>

3
为了帮助提问者和未来的读者,给你的答案增加一些口头上下文会更有帮助。 - Milo

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