// tslint:disable-next-line: import-blacklist import { Observable, BehaviorSubject, Subject } from "rxjs"; import { map } from "rxjs/operators"; export interface IDataSource<T> { readonly data: Observable<T[]>; readonly loading: Observable<boolean>; load(): PromiseLike<T[]>; reload(): PromiseLike<T[]>; filter(filterFn: (obj: any) => boolean); } export class DataSource<T> implements IDataSource<T> { private _loading = new BehaviorSubject<boolean>(false); private _dataArr: T[]; private _data: Subject<T[]>; private _dataPromise: PromiseLike<T[]>; private _filterFn: (obj: any) => boolean; constructor(private _dataFn: () => PromiseLike<T[]>) { this._filterFn = (obj: any) => true; this._data = new BehaviorSubject<T[]>([]); } async load(reload: boolean = false) { if (!this._dataPromise || reload) { return this.reload(); } return await this._dataPromise; } async reload() { this._loading.next(true); this._dataPromise = this._dataFn(); Promise.resolve(this._dataPromise) .then((d) => { this._dataArr = d; this._data.next(d); return d; }).finally(() => this._loading.next(false)); return await this._dataPromise; } get data(): Observable<T[]> { return this._data.pipe(map((arr: T[]) => Array.from(arr).filter(this._filterFn))); } get loading(): Observable<boolean> { return this._loading.asObservable(); } filter(filterFn: (obj: any) => boolean) { if (!filterFn) { filterFn = (obj: any) => true; } this._filterFn = filterFn; if (this._dataArr) { this._data.next(this._dataArr); } } }
// usage this.dataSource = new DataSource<IDebtorOrder>(async () => { const completeOrderHistory = await appDomain.IRequestStoreDebtorOrder.getLastOrders(3); return completeOrderHistory; }); this.dataSource.load();
<ng-container *ngFor="let order of dataSource.data | async"> <app-order-history-item [debtorOrder]="order"></app-order-history-item> </ng-container>
230400cookie-checkTypescript datasource