* ngFor обновляется до получения новых данных - PullRequest
1 голос
/ 18 октября 2019

В настоящее время я работаю над «списком собраний», в котором пользователь может создавать новые собрания и присоединяться к другим собраниям.

Мой стек выглядит следующим образом:

  • FrontEnd: Angular
  • 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 ]

1 голос
/ 18 октября 2019

Хммм, вы уверены, что ваш API завершает POST-запрос, прежде чем вызвать GET-запрос? Я бы посоветовал 1 из 2 вещей:

  • Позвоните своему this.getMeetings(); сразу после ответа на ваш метод POST, а не при закрытии диалога.
  • Если вы добавляете новое собрание, почемуне просто добавить эту встречу в список встреч? Вы можете сделать это после ответа POST с данными с вашего сервера или напрямую со значениями, вставленными в форму
0 голосов
/ 18 октября 2019

добавьте private cdr: ChangeDetectorRef в свой конструктор, затем в функции getMeetings добавьте this.cdr.markForCheck(); после заполнения this.meetings.

пример:

getMeetings() {
        ....
        ....
        // response API service
        this.meetings = response;
        this.cdr.markForCheck();
    }
0 голосов
/ 18 октября 2019

Я бы добавил функцию модального закрытия внутри обратного вызова после запроса, чтобы модальное окно не закрывалось до сохранения собрания в БД. как-то так.

this.httpClient.post(this.apiUrl, data).subscribe((data) => {
  console.log('Event created');
  this.dialogRef.close()
});

Лучше всего посмотреть на тему rxjs.

0 голосов
/ 18 октября 2019

показывать это собрание в списке напрямую, когда вы нажимаете Отправить и присваиваете ему статус saving, затем ждете сохранения в БД.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...