【问题标题】:Why is my ngFor always updating, but array is not为什么我的 ngFor 总是在更新,但数组没有
【发布时间】:2022-01-15 12:31:41
【问题描述】:

问题是:当我启动这个组件时,我的 ngFor div 总是更新并且我的 RAM 变空。据我所知,ngFor 在数组更新时更新,但我的数组(公告)在构造函数中只更新一次。 我有两个 ngFor div:

<mat-tab label="Classroom"> 
        <div *ngFor="let announcement of announcements">
            <mat-card class="example-card">
                <mat-card-header>
                    <mat-card-subtitle>{{"Announcement: " + announcement.text}}</mat-card-subtitle>
                </mat-card-header>
                <mat-card-footer>
                    <div *ngFor="let comment of loadComments(announcement)">
                        <mat-card class="example-card comment">
                            <mat-card-header>
                              <mat-card-subtitle>{{"Comment: " + comment.text}}</mat-card-subtitle>
                            </mat-card-header>
                            <mat-card-content>
                        </mat-card>
                    </div>
                </mat-card-footer>
            </mat-card>
        </div>
    </mat-tab>

ts 文件:

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { environment } from 'src/environments/environment';
import { Announcement } from '../model/announcement';
import { Classroom } from '../model/classroom';
import { User } from '../model/user';
import { Comment } from '../model/comment';
import { ClassroomService } from '../service/classroom.service';
import { CommentService } from '../service/comment.service';
import { AnnouncementService } from '../service/announcement.service';

@Component({
  selector: 'app-view-classroom',
  templateUrl: './view-classroom.component.html',
  styleUrls: ['./view-classroom.component.css']
})
export class ViewClassroomComponent implements OnInit {

  announcements: Announcement[] | undefined;
  comments: Comment[] | undefined;

  constructor(private classroomService: ClassroomService,
              private commentService: CommentService,
              private announcementService: AnnouncementService,
              private formBuilder: FormBuilder) 
  {
    this.classroomService.getClassroomUsers(JSON.parse(localStorage.getItem(environment.classroom) || ''), 'teachers').subscribe(
      (response: User[]) => this.teachers = response);
    this.classroomService.getClassroomUsers(JSON.parse(localStorage.getItem(environment.classroom) || ''), 'students').subscribe(
      (response: User[]) => this.students = response);
    this.classroomService.getClassroomOwner(JSON.parse(localStorage.getItem(environment.classroom) || '')).subscribe(
      (response: User) => this.owner = response);
    this.classroom = JSON.parse(localStorage.getItem(environment.classroom) || '');
    this.announcementService.getAnnouncementsByClassroom(JSON.parse(localStorage.getItem(environment.classroom) || '')).subscribe(
      (response: Announcement[]) => this.announcements = response);
  }

  ngOnInit(): void {
    
  }

  loadComments(announcement: Announcement){
    let an = announcement;
    this.commentService.getCommentsByAnnouncement(an).subscribe(
      (response: Comment[]) => this.comments = response);
    return this.comments;
  }

}

但是当我删除内部 ngFor 时,问题就消失了。 我该怎么办?

【问题讨论】:

  • 第二个是异步调用,可能会导致问题,我建议使用异步管道。
  • @VimalPatel 我在这方面不太好)你能给我举个例子吗?

标签: javascript angular typescript frontend ngfor


【解决方案1】:

你做错了。

  loadComments(announcement: Announcement){
    let an = announcement;
    this.commentService.getCommentsByAnnouncement(an).subscribe(
      (response: Comment[]) => this.comments = response);
    return this.comments; // <-- old values!!
  }

现在这个方法将返回旧版本的this.comments,而不是响应中的那个。

像这样改变方法:

  loadComments(announcement: Announcement):Observable<Comment[]>{
    let an = announcement;
    return this.commentService.getCommentsByAnnouncement(an);
  }

在html文件中:

<ng-container *ngIg="loadComments(announcement) | async as comments"> 
    <div *ngFor="let comment of comments">
    ...
    </div>
</ng-container>

【讨论】:

  • 哇,太好了,对我帮助很大,你是最棒的!
【解决方案2】:

您看到此问题是因为数据是异步填充的。为了解决这个问题,一种解决方案是使用 RxJs 应用响应式编程策略。

第 1 步: 将静态数组定义替换为主题(从 'rxjs' 导入)

announcements: Announcement[] | undefined;
comments: Comment[] | undefined;

// above two line needs to be changed to

announcements$: Subject<Announcement[] | undefined>;
comments$: Subject<Comment[] | undefined>;

第 2 步:更新分配

this.announcementService.getAnnouncementsByClassroom(
  JSON.parse(localStorage.getItem(environment.classroom) || '')
).subscribe(
  // (response: Announcement[]) => this.announcements = response <- update this to:
  (response: Announcement[]) => this.announcements$.next(response)
);

this.commentService.getCommentsByAnnouncement(an).subscribe(
  // (response: Comment[]) => this.comments = response <- update this to:
  (response: Comment[]) => this.comments$.next(response)
);
// return this.comments; <- this is not required any more

第 3 步:更新 HTML

<!-- old -->
<div *ngFor="let announcement of announcements">
<!-- new -->
<div *ngFor="announcements$ | async as announcement">

<!-- old -->
<div *ngFor="let comment of loadComments(announcement)">
<!-- new -->
<div *ngFor="comments$ | async as comment">

【讨论】:

  • 它有帮助,但我仍然不知道如何为每个公告更新此 cmets$。当我尝试像 {{loadComments(announcement$}} 这样的事情时,它又发生了。
  • 你能在 Stackblitz 上创建一个工作演示并分享链接吗?看了demo后,也许我可以提供更多帮助!
【解决方案3】:

只是改变

*ngFor="let comment of loadComments(announcement)"

*ngFor="let comment of comments"

loadComments(announcement: Announcement) {
    this.commentService.getCommentsByAnnouncement(announcement).subscribe((response: Comment[]) => {
        this.comments = response
    })
}

【讨论】:

  • 但我需要为每个公告获取新的 cmets 数组。在这种情况下,我将只更新一次 cmets 数组。
猜你喜欢
  • 2018-07-03
  • 2023-01-12
  • 2020-04-25
  • 2019-09-22
  • 1970-01-01
  • 1970-01-01
  • 2017-11-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多