* ngFor在获取新数据之前正在更新

时间:2019-10-18 07:49:50

标签: javascript html angular typescript asynchronous

我目前正在“会议列表”上工作,用户可以在其中创建新会议并加入其他会议。

我的堆栈看起来像这样:

  • 前端:角度
  • 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(角度材料),用户可以在其中输入有关会议的一些基本信息。

  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取回之前刷新。因此,只有在刷新页面或创建下一个项目时才会显示新事件。

GIF of the problem

我现在想做的是以某种方式等待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可能正在接受检查,但是新数据还不存在。

4 个答案:

答案 0 :(得分:1)

嗯,您确定在调用GET请求之前您的API已完成POST请求吗?我建议2件事情中的1件:

  • 在POST方法响应后而不是在关闭对话框后立即致电this.getMeetings();
  • 如果要添加新会议,为什么不简单地将该会议添加到会议列表?您可以在POST响应后使用服务器中的数据进行操作,也可以直接使用表格中插入的值进行操作

答案 1 :(得分:0)

当您点击“提交”并将其设置为saving状态,然后等待数据库保存时,直接在列表中显示此会议。

答案 2 :(得分:0)

我会在post request回调中添加close modal函数,这样在会议保存到db之前不会关闭modal。像这样的东西。

TracingHttpCientBuilder

一个更好的选择是查看rxjs主题。

答案 3 :(得分:0)

在构造函数中添加private cdr: ChangeDetectorRef,然后在此get.meetings函数中添加this.cdr.markForCheck();。填充会议。

示例:

getMeetings() {
        ....
        ....
        // response API service
        this.meetings = response;
        this.cdr.markForCheck();
    }