如何在类似Om的不可变应用程序状态下对关系数据进行建模

How to model relational data in an Om-like immutable app state

本文关键字:关系 数据 建模 程序状态 应用 Om 不可变      更新时间:2023-12-16

我正试图决定是使用更传统的Flux实现还是使用类似Om的结构。我真的很喜欢在javascript中使用带有游标的单个不可变应用程序状态对象的想法,但我不确定如何对关系数据建模。我正在考虑使用类似Morearty的东西。

我的问题是如何避免重复数据并处理从服务器发送的嵌套关系数据?假设我有一个REST端点,它为我提供库存,并且每个库存项都有一个嵌套的供应商。我还有一个供应商的端点。我希望在我的应用程序状态下有一个所有供应商的列表,但也要在我的库存项目中引用这些供应商。当我对供应商进行更新时,我希望它对引用该供应商的所有库存项进行更改。

类似Om的结构适用于这种应用程序吗?还是一个更传统的Flux风格的应用程序和谨慎的商店会更好?

您可能想研究像Redux这样的"通量"框架。它非常棒——我们在Docker使用它。以下是为什么它很好,以及它如何帮助你。

为什么要使用redux

它使用单店模式。所有存储都将Redux内部的状态保存在自己的密钥中。Redux保存状态的一个示例是:

{
  vendors: [{...}, ...], // The "vendor" store updates this part of the state
  inventory: [...] // the "inventory" store updates this part of the state
}

Redux或Redux提供程序是所有组件的父级。因此,所有组件都作为道具接收状态。

单店模式如何改善现状

  1. 每个响应Redux内操作的单独"存储"只更新状态对象的一个部分。例如,"vendor"存储仅更新状态的"vendor"密钥。每次操作发生时,单个存储都会被赋予当前状态。这使得商店变得完全纯净这非常适合测试、不可变数据、热重新加载、倒带等。

  2. 因为您的单个顶级Redux存储保存所有状态,所以每个组件都可以将该状态作为道具接收,并在该状态发生变化时自动重新渲染,即使是来自层次结构之外的不相关组件。

这里有一个单一商店的例子,所以你可以得到这个想法:

import assign from 'object-assign';
import consts, { metrics, loading, URLS } from 'consts';
const actions = {
  // As you can see, each action within a store accepts the current "state" 
  // and can modify that state by returning new data.
  [metrics.FETCH_METRICS_PENDING]: (state, data) => {
    return assign({}, state, {status: loading.PENDING});
  },
  [metrics.FETCH_METRICS_SUCCESS]: (state, data) => {
    return assign({}, state, {status: loading.SUCCESS, metrics: data.payload});
  },
  [metrics.FETCH_METRICS_FAILURE]: (state, data) => {
    return assign({}, state, {status: loading.FAILURE});
  },
  [metrics.OBSERVE_METRICS_DATA]: (state, data) => {
    let metrics = state.metrics.slice().concat(data.payload);
    return assign({}, state, {metrics});
  }
}
// This is the single method that's exported and represents our store.
// It accepts the current state as its primary argument, plus the action
// data as a payload.
//
// This delegates to the methods above depending on `data.type`.
export default function metricStore(state = {}, data) {
  if (typeof actions[data.type] === "function") {
    return actions[data.type](state, data);
  }
  return state;
}

这个如何对关系数据建模

每次通过操作创建者请求数据时,它都可以调度多个操作,这些操作一起更新供应商和库存状态。这将在一次渲染中反映在您的应用程序中。