如何将Observable @Input 传递给Angular组件存储?

huangapple go评论57阅读模式
英文:

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:

&lt;sales-history
    [salesHistory]=&quot;salesHistory$ | async&quot;&gt;
&lt;/sales-history&gt;

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&lt;SalesHistoryState&gt; {
    constructor(private whsService: WarehouseService) {
        super({
            salesHistory: [],
            warehousesToShow: []
        });
    }

    salesHistoryWithWhColors$: Observable&lt;SalesHistoryLine[]&gt; = this.select(state =&gt; state.salesHistory.filter(value =&gt; !! value).map(csh =&gt; ({
        ...csh,
        color: this.whsService.whsColorLookup[csh.warehouseId]
      })));

    warehousesToShow$: Observable&lt;number[]&gt; = this.select(state =&gt; state.warehousesToShow);

    salesHistory$: Observable&lt;SalesHistoryLine[]&gt; = this.select(
        this.salesHistoryWithWhColors$,
        this.warehousesToShow$,
        (salesHistoryLines, warehousesToShow) =&gt; salesHistoryLines.filter(shl =&gt;
        (warehousesToShow ? warehousesToShow.includes(shl.warehouseId) : true)));

    setWarehousesToShow = this.updater((state, warehousesToShow: number[]) =&gt; ({
        ...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&lt;SalesHistoryLine[]&gt; = this.select(state =&gt; state.salesHistory).pipe(filter(value =&gt; !! value)).pipe(map(csh =&gt; csh.map(line =&gt; ({
    ...line,
    color: this.whsService.whsColorLookup[line.warehouseId]
  }))));

huangapple
  • 本文由 发表于 2023年5月21日 19:04:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/76299544.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定