首页 > 解决方案 > 无法读取属性

问题描述

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

SlackBlitz 链接 - slackblitz

错误类型错误:无法读取未定义的属性“作者”

HTML 文件 -

<div fxFlex="50" *ngIf="dish">
  <mat-list>
    <mat-list-item>
      <h2> Comments </h2>        
    </mat-list-item>
    <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="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>
<div [hidden]="dish">
  <mat-spinner></mat-spinner><h4>Loading . . . Please Wait</h4>
</div>

打字稿文件 -

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

}

标签: javascriptangularangular-forms

解决方案


问题是您尝试comment.author在 HTML 模板中访问,但commentDishdetailsComponent类中是undefinednull.

您分配值的唯一位置comment是在方法内的第一行,onSubmit但在下面几行,您分配null给它。

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;  // here's what I mentionned
    this.commentsForm.reset({
      author: '',
      comment: '',
      rating: 5
    });
}

如果你包含comment在你的 中*ngIf,它应该可以工作。

<mat-list>
  <mat-list-item *ngIf="comment && commentsForm.valid" [hidden]="comment">
    <p mat-line>
      <span> {{comment.comment}} </span>
    </p>
    ...

推荐阅读