Angular не обновляет пользовательский интерфейс после завершения обещания

#angular #promise #es6-promise #angular-changedetection

#angular #обещание #es6-обещание #angular-changedetection

Вопрос:

У меня есть следующий сервис:

 @Injectable({ providedIn: 'root' })
export class ContextService {

  contextSubject = new ReplaySubject<ContextModel>(1);

  context: ContextModel = {};

  setContext(context: ContextModel) {
    console.log('contest service set context');
    console.dir(context);
    this.context = context;
    this.contextSubject.next(this.context);
  }

  public get contextObservable(): Observable<ContextModel> {
    return this.contextSubject.asObservable();
  }
}
  

У меня есть эта служба, внедренная в компонент, и я подписываюсь на нее.

   async ngOnInit() {

    this.contextService.contextObservable.pipe(takeUntil(this.subDestroy)).subscribe(async () => {
      await this.loadData();
    });

  }

  ...

  async loadData() {
    this.loading = true;

    await this.dataSource.query();

    this.loading = false;

    setTimeout(() => { this.cd.detectChanges(); }, 500);
  }
  

который вызывает метод источника данных angular material:

   async query():Promise<void> {
...
    let result = await this.inventoryService.query(skip, take, (item : InventoryItem) => { return this.filterFunc(item) }, this.sort);
...
  }
  

который, в свою очередь, вызывает службу, которая возвращает некоторые фиктивные данные

   async query(skip = 0, take = 20, filters : (obj: InventoryItem) => boolean, sort : Sort) : Promise<PagedResult<InventoryItem>> {

    let p = new Promise<PagedResult<InventoryItem>>((resolve, reject) => {
      let res : PagedResult<InventoryItem> = {
        count: 1,
        items: [
          {
            id: '1',
            name: 'a',
            quantity: 123,
            rarity: 'b',
            subtype: 'c',
            type: 'd'
          }
        ],
      };

      setTimeout(() => {
        resolve(res);
      }, 1000);
    });

    return p;
  }
  

Затем откуда-то я делаю следующее:

     this.contextService.setContext({ ... });
  

Моя проблема заключается в следующем:
При первой загрузке страницы все в порядке.
После этого, если я не вызываю cd.detectChanges() , пользовательский интерфейс остается в состоянии загрузки навсегда или до тех пор, пока я не нажму на элемент формы (например, ввод).

Я не знаю, имеет ли значение следующее или нет: Компонент верхнего уровня экспортируется как веб-компонент с использованием элементов angular. Я использую angular material, и у меня есть таблица angular material и счетчик прогресса на странице.

РЕДАКТИРОВАТЬ: на самом деле мне приходится использовать setTimeout(() => { this.cd.detectChanges(); }, 500); , чтобы заставить его работать каждый раз.

Комментарии:

1. Здесь: async query():Promise<void> — что возвращается? (И побочный вопрос, есть ли веская причина для смешивания наблюдаемого рецепта с рецептом Promise?)

2. 1. Он возвращает пустое обещание. и выдает новое значение для наблюдаемых элементов. Я не включил этот код this.items.next(result.items); . 2. Мне больше нравятся обещания, не было особой причины