【问题标题】:How to interact between multiple state models without duplicate store objects - NGXS如何在没有重复存储对象的情况下在多个状态模型之间进行交互 - NGXS
【发布时间】:2020-06-19 22:56:39
【问题描述】:

为了降低我的应用程序中所有状态的复杂性,我决定使用 NGXS,因为它使用 TypeScript 的方式进行实现,非常适合 Angular 架构。但是第一个问题出现得很快,因为与 NGRX 相比,NGXS 没有添加额外的解耦 reducer 层。

在多个状态模型之间进行交互的最佳做法是什么?假设您要操作状态 B,但此操作需要状态 A 的属性。我在文档中找到了可以处理此问题的共享状态概念,但这也是有限的,因为我无法在选择器中使用共享状态来根据状态 A 和 B 所需的操作为 UI 提供特定选择。

例如,我得到了商店中展示的以下模型。本例中的问题,从DeviceState 中获取selectedDevicedeviceId 以在DeviceHistoryState 中使用它以返回所选设备的所有项目历史记录的最佳方法是什么。

当然,我可以将 DeviceHistory 集成到 Device 模型中,但这并不能解决在多个状态之间执行操作的问题。我也不想将 selctedDevice 复制到 DeviceHistoryStateModel 中。

export interface Device {
    deviceId: string;
    // More device details
}
export interface DeviceHistory {
    deviceId: string;
    itemHistoryMap: Map<number, ItemHistory[]>;
}

export class DeviceStateModel {
    devices: Device[];
    selectedDevice: Device;
}

@State<DeviceStateModel>({
    name: 'devices',
    defaults: {
        devices: [],
        selectedDevice: null
    }
})
export class DeviceState {

}
export class DeviceHistoryStateModel {
    devicesHistory: DeviceHistory[];
}

@State<DeviceHistoryStateModel>({
    name: 'devicesHistory',
    defaults: {
        devicesHistory: []
    }
})
export class DeviceHistoryState {
    @Selector()
    public static getHistory(state: DeviceHistoryStateModel) {
       // ??? Best practise to return all the item histories of the selcted device 
    }

    @Action(GetItemHistory)
    public getItemHistory() {
        // Stores the item history for the device
    }
}

【问题讨论】:

    标签: angular typescript redux rxjs ngxs


    【解决方案1】:

    最简单的选择是使用Joining Selector

    @Selector()
    public static getHistory(state: DeviceHistoryStateModel, deviceState: DeviceStateModel) {
           // ??? Best practise to return all the item histories of the selcted device 
           const selectedDevice = deviceState.selectedDevice;
          //... get history items that match
     }
    

    第二个选项可能是您想要的,因为您希望在 selectedDevice 值更改时自动重新评估此历史选择器。

    您可能还想检查您正在运行的 NGXS 的版本,因为选择器的注入参数选项最近(和即将发生的更改)。

    您还可以使用动态选择器来实现这一点,传递设备 ID 并获取该设备的过滤历史记录:

    static getHistory(deviceId: string) {
        return createSelector([DevicesHistoryState], (state: DevicesHistoryStateModel) => {
          return state.devicesHistory.filter(h => h.deviceId === deviceId);
        });
      }
    

    【讨论】:

    • 有效,但不要忘记通过@Selector([DeviceState])注入其他状态
    • 我正在尝试实现答案中的第一个选项。只是想知道如何从静态方法中引用商店?不会是编译错误吧?
    • @Schrödingerkōder 你是正确的 - 我不确定我当时在想什么。加入选择器将是最佳选择.. 或者您可以使其与动态选择器一起使用,将所选设备 ID 作为参数传递。我会在这里更新我的答案,感谢您指出这一点!
    猜你喜欢
    • 2021-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-10
    • 2020-07-04
    • 2018-04-06
    • 1970-01-01
    相关资源
    最近更新 更多