英文:
How to pass Observable @Input to angular component store?
问题
I'm trying to pass an Observable array into an inner 'dumb' component, do some filtering/mapping on it and then pass it to a custom table object that requires an observable as input. My outer component pipes the observable asynchronously into an @Input with a setter so that the inner component gets it as a regular array.
Outer component:
<sales-history [salesHistory]="salesHistory$ | async"></sales-history>
When the @Input
loads it updates my component store:
@Input() set salesHistory(val: SalesHistoryLine[]) {
this.store.update({ salesHistory: val });
}
This update
method is an extension of angular's updater
method that updates the state with the provided prop.
My store:
export interface SalesHistoryState {
isLoaded?: boolean;
salesHistory: SalesHistoryLine[];
warehousesToShow: number[];
}
@Injectable()
export class SalesHistoryStore extends OodleComponentStore<SalesHistoryState> {
constructor(private whsService: WarehouseService) {
super({
salesHistory: [],
warehousesToShow: []
});
}
salesHistoryWithWhColors$: Observable<SalesHistoryLine[]> = this.select(state => state.salesHistory.filter(value => !!value).map(csh => ({
...csh,
color: this.whsService.whsColorLookup[csh.warehouseId]
})));
warehousesToShow$: Observable<number[]> = this.select(state => state.warehousesToShow);
salesHistory$: Observable<SalesHistoryLine[]> = this.select(
this.salesHistoryWithWhColors$,
this.warehousesToShow$,
(salesHistoryLines, warehousesToShow) => salesHistoryLines.filter(shl =>
(warehousesToShow ? warehousesToShow.includes(shl.warehouseId) : true)));
setWarehousesToShow = this.updater((state, warehousesToShow: number[]) => ({
...state,
warehousesToShow
}));
}
When I open this dialog component, the sales history does not load the first time I open it, only the second time. What am I doing wrong?
ngOnInit:
ngOnInit(): void {
this.tableBuilder = new TableBuilder(this.store.salesHistory$, meta$)
}
英文:
I'm trying to pass an Observable array into an inner 'dumb' component, do some filtering/mapping on it and then pass it to a custom table object that requires an observable as input. My outer component pipes the observable asynchronously into an @Input with a setter so that the inner component gets it as a regular array.
Outer component:
<sales-history
[salesHistory]="salesHistory$ | async">
</sales-history>
When the @Input
loads it updates my component store:
@Input() set salesHistory(val: SalesHistoryLine[]) {
this.store.update({ salesHistory: val });}
This update
method is an extension of angular's updater
method that updates the state with the provided prop.
My store:
export interface SalesHistoryState {
isLoaded?: boolean;
salesHistory: SalesHistoryLine[];
warehousesToShow: number[];
}
@Injectable() export class SalesHistoryStore extends OodleComponentStore<SalesHistoryState> {
constructor(private whsService: WarehouseService) {
super({
salesHistory: [],
warehousesToShow: []
});
}
salesHistoryWithWhColors$: Observable<SalesHistoryLine[]> = this.select(state => state.salesHistory.filter(value => !! value).map(csh => ({
...csh,
color: this.whsService.whsColorLookup[csh.warehouseId]
})));
warehousesToShow$: Observable<number[]> = this.select(state => state.warehousesToShow);
salesHistory$: Observable<SalesHistoryLine[]> = this.select(
this.salesHistoryWithWhColors$,
this.warehousesToShow$,
(salesHistoryLines, warehousesToShow) => salesHistoryLines.filter(shl =>
(warehousesToShow ? warehousesToShow.includes(shl.warehouseId) : true)));
setWarehousesToShow = this.updater((state, warehousesToShow: number[]) => ({
...state,
warehousesToShow
}));
}
When I open this dialog component, the sales history does not load the first time I open it, only the second time. What am I doing wrong? I need the salesHistory$ observable to emit to my table object.
ngOnInit:
ngOnInit(): void {
this.tableBuilder = new TableBuilder(this.store.salesHistory$, meta$)
}
答案1
得分: 0
我找到了我的问题。我在选择 salesHistory$
可观察对象的时候出现了错误。已经更正的代码如下:
salesHistoryWithWhColors$: Observable<SalesHistoryLine[]> = this.select(state => state.salesHistory).pipe(
filter(value => !!value)
).pipe(
map(csh => csh.map(line => ({
...line,
color: this.whsService.whsColorLookup[line.warehouseId]
})))
);
英文:
I found my problem. I was selecting one of the observables for the salesHistory$
observable incorrectly. The corrected code is:
salesHistoryWithWhColors$: Observable<SalesHistoryLine[]> = this.select(state => state.salesHistory).pipe(filter(value => !! value)).pipe(map(csh => csh.map(line => ({
...line,
color: this.whsService.whsColorLookup[line.warehouseId]
}))));
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论