You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Observable @Input传入Angular组件商店?首次加载失败排查

问题分析与解决方案

问题根源

首次打开对话框不加载数据、第二次才加载的核心原因是:@Input setter中调用的this.store.update并未正确更新ComponentStore的状态。

你的SalesHistoryStore仅定义了setWarehousesToShow这个updater方法,却没有专门用于更新salesHistory状态的updater。直接调用this.store.update(假设OodleComponentStore未提供默认update方法)不会触发状态变更,导致salesHistory$始终发出初始空数组。第二次打开时,父组件的salesHistory$已有缓存值,async管道会立即传递数据,此时setter可能在组件初始化前触发,才让表格拿到有效数据。

修复步骤

1. 在Store中添加更新salesHistory的updater方法

修改SalesHistoryStore,新增专门的updater处理salesHistory状态更新:

@Injectable() 
export class SalesHistoryStore extends OodleComponentStore<SalesHistoryState> {
    constructor(private whsService: WarehouseService) {
        super({
            salesHistory: [],
            warehousesToShow: [],
            isLoaded: false // 显式标记初始未加载状态
        });
    }

    // 新增:更新salesHistory的updater方法
    updateSalesHistory = this.updater((state, salesHistory: SalesHistoryLine[]) => ({
        ...state,
        salesHistory,
        isLoaded: true // 标记数据已加载
    }));

    // 原有代码保持不变
    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.select(state => state.isLoaded),
        this.salesHistoryWithWhColors$,
        this.warehousesToShow$,
        (isLoaded, salesHistoryLines, warehousesToShow) => {
            if (!isLoaded) return [];
            return salesHistoryLines.filter(shl =>
                warehousesToShow ? warehousesToShow.includes(shl.warehouseId) : true
            );
        }
    );

    setWarehousesToShow = this.updater((state, warehousesToShow: number[]) => ({
        ...state,
        warehousesToShow
    }));
}

2. 修改@Input setter,调用正确的updater

将子组件的@Input setter改为调用新增的updateSalesHistory方法:

@Input() set salesHistory(val: SalesHistoryLine[]) {
  // 过滤空值,避免覆盖有效状态
  if (val?.length) {
    this.store.updateSalesHistory(val);
  }
}

验证逻辑

修复后,当父组件通过async管道传递数据时,setter会触发Store状态更新,salesHistory$会立即发出过滤后的有效数据,TableBuilder能实时接收到数据,首次打开对话框即可正常显示销售记录。

内容的提问来源于stack exchange,提问作者Sora Teichman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 05:44:55