为什么我的 ngFor 总是在更新,而数组却没有
Why is my ngFor always updating, but array is not
问题是:当我启动这个组件时,我的 ngFor div 总是更新并且我的 RAM 变空了。据我所知,当数组更新时 ngFor 会更新,但我的数组(公告)只在构造函数中更新一次。
我有两个 ngFor divs:
<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 时,问题就消失了。
我该怎么办?
只是改变
*ngFor="let comment of loadComments(announcement)"
至
*ngFor="let comment of comments"
和
loadComments(announcement: Announcement) {
this.commentService.getCommentsByAnnouncement(announcement).subscribe((response: Comment[]) => {
this.comments = response
})
}
您看到这个问题是因为数据是异步填充的。为了解决这个问题,解决方案之一是使用 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">
你的做法是错误的。
loadComments(announcement: Announcement){
let an = announcement;
this.commentService.getCommentsByAnnouncement(an).subscribe(
(response: Comment[]) => this.comments = response);
return this.comments; // <-- old values!!
}
现在这个方法将 return 旧版本的 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>
问题是:当我启动这个组件时,我的 ngFor div 总是更新并且我的 RAM 变空了。据我所知,当数组更新时 ngFor 会更新,但我的数组(公告)只在构造函数中更新一次。 我有两个 ngFor divs:
<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 时,问题就消失了。 我该怎么办?
只是改变
*ngFor="let comment of loadComments(announcement)"
至
*ngFor="let comment of comments"
和
loadComments(announcement: Announcement) {
this.commentService.getCommentsByAnnouncement(announcement).subscribe((response: Comment[]) => {
this.comments = response
})
}
您看到这个问题是因为数据是异步填充的。为了解决这个问题,解决方案之一是使用 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">
你的做法是错误的。
loadComments(announcement: Announcement){
let an = announcement;
this.commentService.getCommentsByAnnouncement(an).subscribe(
(response: Comment[]) => this.comments = response);
return this.comments; // <-- old values!!
}
现在这个方法将 return 旧版本的 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>