无法读取 属性

Cannot Read Property

当我尝试 运行 这些时,我的控制台出现以下错误。我试着检查作者 属性 但我无法解决它。作者在名为 comment.ts 的文件中定义,其中作者是一个字符串。

StackBlitz

错误类型错误:无法读取未定义的 属性 'author'

控制台指向这些行 -

<input matInput formControlName="author" placeholder="Name" type="text" required>
            <mat-error *ngIf="formErrors.author">
              {{formErrors.author}}
            </mat-error>

Typescript 文件代码 - (dishdetails.component.ts)

    export class DishdetailsComponent implements OnInit {
  dish: Dish;
  dishIds: string[];
  prev: string;
  next: string;
  commentsForm: FormGroup;
  comment: Comment;
  formErrors: {
    'author': '';
    'comment': '';
  };

  validationMessages: {
    'author': {
      'required': 'Author Name is required.',
      'minlength': 'Author Name must be at least 2 characters long.',
      'maxlength': 'Author Name cannot be more than 25 characters long.'
    },
    'comment': {
      'required': 'Comment is required.',
      'minlength': 'Comment must be at least 1 characters long.'
    }
   };
  constructor(private dishservice: DishService, private route: ActivatedRoute,
    private location: Location,
    private fb: FormBuilder) {
      this.createForm();
    }

  ngOnInit() {
    this.dishservice.getDishIds().subscribe(dishIds => this.dishIds = dishIds);
    this.route.params.pipe(
      switchMap((params: Params) => this.dishservice.getDish(params['id'])))
      .subscribe(dish => { this.dish = dish; this.setPrevNext(dish.id); });
  }
  setPrevNext(dishId: string) {
      const index = this.dishIds.indexOf(dishId);
      this.prev = this.dishIds[(this.dishIds.length + index - 1) % this.dishIds.length];
      this.next = this.dishIds[(this.dishIds.length + index + 1) % this.dishIds.length];
  }
  goBack(): void {
    this.location.back();
  }

  createForm() {
     this.commentsForm = this.fb.group({
      author: ['', [Validators.required, Validators.minLength(2), Validators.maxLength(25)]],
      comment: ['', [Validators.required, Validators.minLength(1)]],
      rating : 5
    });
    this.commentsForm.valueChanges
    .subscribe(data => this.onValueChanged(data));
  }
  onValueChanged(data?: any) {
    if (!this.commentsForm) {
      return;
    }
    const form = this.commentsForm;
    for (const field in this.formErrors) {
      if (this.formErrors.hasOwnProperty(field)) {
        this.formErrors[field] = '';
        const control = form.get(field);
        if (control && control.dirty && !control.valid) {
          const messages = this.validationMessages[field];
          for (const key in control.errors) {
            if (control.errors.hasOwnProperty(key)) {
              this.formErrors[field] += messages[key] + ' ';
            }
          }
        }
      }
    }
  }

  onSubmit() {
    this.comment = this.commentsForm.value;
    const d = new Date();
    this.comment.date = d.toISOString();
    this.dish.comments.push(this.comment);
    console.log(this.comment);
    this.comment = null;
    this.commentsForm.reset({
      author: '',
      comment: '',
      rating: 5
    });
  }

对应的HTML文件-(dishdetails.component.html)

<mat-list-item *ngFor="let comment of dish.comments">
          <p mat-line>
            <span> {{comment.comment}} </span>
          </p>
          <p mat-line>
            <span> {{comment.rating}} Stars</span>
          </p>
          <p mat-line>
            <span> -- {{comment.author}} {{comment.date | date}} </span>
          </p>
        </mat-list-item>
      </mat-list>
      <mat-list>
        <mat-list-item *ngIf=" comment && commentsForm.valid" [hidden]="comment">
          <p mat-line>
            <span> {{comment.comment}} </span>
          </p>
          <p mat-line>
            <span> {{comment.rating}} Stars</span>
          </p>
          <p mat-line>
            <span> -- {{comment.author}}</span>
          </p>
        </mat-list-item>
        </mat-list>

      <form novalidate [formGroup]="commentsForm" (ngSubmit)="onSubmit()">
        <p>
          <mat-form-field class="full-width">
            <input matInput formControlName="author" placeholder="Name" type="text" required>
            <mat-error *ngIf="formErrors.author">
              {{formErrors.author}}
            </mat-error>
          </mat-form-field>
        </p>
        <p>
          <mat-slider formControlName="rating" thumbLabel tickInterval="1" min="1" max="5" step="1" value="5"></mat-slider>   
        </p>
        <p> 
          <mat-form-field class="full-width">
            <textarea matInput formControlName="comment" placeholder="Your Comment" rows="12" required></textarea>
            <mat-error *ngIf="formErrors.comment">
              {{formErrors.comment}}
            </mat-error>
          </mat-form-field>
        </p>
        <button type="submit" mat-button class="background-primary text-floral-white" [disabled]="commentsForm.invalid">Submit</button>
      </form>
    </div>

    }

formErrors.author 属性 在您向 commentsForm 输入任何内容之前未定义。您有 2 个选择:

选项 1

formErrors 提供默认值。

formErrors: { 'author': '', 'comment': '' } = { 'author': '', 'comment': ''};

选项 2

或者更好,使用 Elvis operator when accessing the properties. In Angular it's called safe navigation operator ?..

将模板中出现的所有 formErrors.author 替换为 formErrors?.author。 TBH,在尝试访问对象的属性以避免这些 undefined 错误时,最好始终在模板中包含 Elvis 运算符。

操作员在尝试访问它的属性之前检查是否定义了 formErrors