Я использую компонент для рендеринга таблицы, такой как данные, я даю ему список столбцов, данные, как данные сопоставляются с каждым столбцом и, наконец, список каналов для применения к данным каждого столбца.
Пока все хорошо, единственная проблема заключается в том, что один из этих каналов является асинхронным каналом...
Поэкспериментировав некоторое время, я обнаружил, что когда асинхронный канал используется в шаблоне, метод преобразования вызывается несколько раз. Однако, если я использую его программно, метод преобразования вызывается только один раз (время, когда я его вызываю).
Я предполагаю, что причина, по которой он вызывается несколько раз в шаблоне, заключается в том, что это нечистый канал, но как я могу справиться с этим программно?
Вот plunker, демонстрирующий то, что я только что сказал:
@Injectable()
export class AsyncProvider {
constructor() {}
getById(id: number) {
// Just some mock data
return Observable.of({id, times_five: id*5}).delay(1000);
}
}
@Component({
selector: 'my-app',
providers: [AsyncPipe, AsyncProvider]
template: `
<div>
<p>Template async pipe</p>
<p>{{ asyncObj | async | json }}</p>
<hr>
<p>Programmatically async pipe</p>
<p>{{ asyncObjPiped | json }}</p>
</div>
`,
directives: []
})
export class App {
constructor(
private _provider: AsyncProvider,
private _async: AsyncPipe
) {
this.asyncObj = this._provider.getById(123);
this.asyncObjPiped = this._async.transform(this.asyncObj);
}
}
EDIT: Потому что AsyncPipe выполняет markForCheck() для ChangeDetectorRef при получении новых значений, я также пробовал следующее:
export class App {
constructor(
private _provider: AsyncProvider,
private _async: AsyncPipe,
private _ref: ChangeDetectorRef,
) {
this.asyncObj = this._provider.getById(123);
this.asyncObjPiped = this._async.transform(this.asyncObj);
setInterval(() => {
this._ref.detectChanges();
}, 1000);
}
}
Без особого успеха :(