javascript - *ngFor 在获取新数据之前正在更新
问题描述
我目前正在制作“会议列表”,用户可以在其中创建新会议并加入其他会议。
我的堆栈看起来像这样:
- 前端:角
- API:Firebase 云函数
- 数据库:Firebase 实时数据库
对于会议列表,我使用此标记,因为它应该呈现每个会议的列表及其名称。
<div class="container">
<h2>Aktuelle Meetings</h2>
<div class="cardContainer" *ngFor="let meeting of meetings">
<div class="meeting">
<div class="meetingText">
<p class="titleText">{{ meeting[1].title }}</p>
</div>
</div>
</div>
<div class="createMeeting">
<button class="floating" mat-fab (click)="openCreateMeeting()">
<mat-icon>add</mat-icon>
</button>
</div>
</div>
openCreateMeeting()
正在打开一个 MaterialDialog (Angular Material),用户可以在其中输入有关会议的一些基本信息。
openCreateMeeting(): void {
const dialogConfig = new MatDialogConfig();
dialogConfig.autoFocus = true;
const dialogRef = this.dialog.open(NewMeetingComponent, dialogConfig);
dialogRef.afterClosed().subscribe((data) => {
this.getMeetings();
});
}
getMeeting()
发送 API 调用以从数据库中获取会议。
当用户创建新事件时,它会触发我的“apiService”,其中包括创建新会议的功能。
public postMeeting(
eventTitle,
eventDescription,
eventLocation,
eventDate,
eventOwner
): void {
console.log('creating an event ...');
const data = {
title: eventTitle,
description: eventDescription,
location: eventLocation,
date: eventDate,
owner: eventOwner,
participants: eventOwner,
};
this.httpClient.post(this.apiUrl, data).subscribe((data) => {
console.log('Event created');
});
}
但是,当我创建新事件时,新事件不会出现在列表中。它会在新项目从 API/DB 中返回之前刷新。因此,仅当我刷新页面或创建下一个项目时才会显示新事件。
我现在想要做的是以某种方式等待 API 调用完成,然后再刷新我的*ngFor
.
问题:那么在重新渲染 *ngFor 之前,我将如何等待数据出现?
我尝试了什么:
我试图将changeDetector.markForCheck()
.
dialogRef.afterClosed().subscribe((data) => {
this.getMeetings();
this.changeDetector.markForCheck();
});
将 changeDetector 直接包含在我的getMeetings()
.
public getMeetings() {
const meetings = this.httpClient.get(this.apiUrl);
this.changeDetector.markForCheck();
return meetings;
}
这并没有解决问题,但使我的应用程序崩溃并给了我这个错误:
StaticInjectorError(Platform: core)[MeetingListComponent -> ChangeDetectorRef]:
NullInjectorError: No provider for ChangeDetectorRef!
NullInjectorError: StaticInjectorError(AppModule)[MeetingListComponent -> ChangeDetectorRef]:
StaticInjectorError(Platform: core)[MeetingListComponent -> ChangeDetectorRef]:
NullInjectorError: No provider for ChangeDetectorRef!
at NullInjector.get (core.js:778)
at resolveToken (core.js:2564)
at tryResolveToken (core.js:2490)
at StaticInjector.get (core.js:2353)
at resolveToken (core.js:2564)
at tryResolveToken (core.js:2490)
at StaticInjector.get (core.js:2353)
at resolveNgModuleDep (core.js:26403)
at NgModuleRef_.get (core.js:27491)
at injectInjectorOnly (core.js:657)
at resolvePromise (zone-evergreen.js:797)
at resolvePromise (zone-evergreen.js:754)
at zone-evergreen.js:858
at ZoneDelegate.invokeTask (zone-evergreen.js:391)
at Object.onInvokeTask (core.js:34182)
at ZoneDelegate.invokeTask (zone-evergreen.js:390)
at Zone.runTask (zone-evergreen.js:168)
at drainMicroTaskQueue (zone-evergreen.js:559)
at ZoneTask.invokeTask [as invoke] (zone-evergreen.js:469)
at invokeTask (zone-evergreen.js:1603)
这没有做任何事情,因为 angular 可能正在接受检查,但新数据还没有。
解决方案
嗯,您确定您的 API 在调用 GET 请求之前完成了 POST 请求吗?我会建议两件事中的一件:
this.getMeetings();
在您的 POST 方法响应之后而不是在您关闭对话框时调用您的权利。- 如果您要添加一个新会议,为什么不简单地将该会议添加到会议列表中呢?您可以在 POST 响应之后使用服务器中的数据执行此操作,也可以直接使用表单中插入的值执行此操作
推荐阅读
- javascript - 为什么 MobX 不能用作状态容器?
- python-3.x - Python 中的快速 GUID
- c++ - 将参数包解压缩到 std::initializer_list 中?
- r - 匹配字符范围内的元素 n 次
- tfs - VSTS - 如果已删除,则恢复团队项目
- git - 如何使用命令行在 Gitlab 中创建本地存储库和远程存储库?
- ruby - 来自孩子的标准输出的 Ruby 管道未关闭/如何检测空管道
- c# - 如何存储来自通用对象的验证器列表。C#
- angular - 将来自 API 的数据存储在变量 [Angular] 中
- ios - 如何通过单击 UITableView 的上一个单元格来解锁下一个单元格?