#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. Мне больше нравятся обещания, не было особой причины