【问题标题】:ngrx share state between appsngrx 在应用程序之间共享状态
【发布时间】:2018-03-29 13:14:43
【问题描述】:

目标

我有两个应用程序(A 和 B),其中 B 是 A 的 80%。A 使用 ngrx,B 将需要大约 20% 的相同状态。我想通过为 B 创建一个新的根状态并将 A 中我想要的 reducer 放在它上面,在应用程序之间共享相关的操作、效果、reducer 和选择器/投影。

问题

问题在于选择器特定于根状态或至少是功能状态(例如:createSelector<RootStateA, Tsomething>((store) => store.something))。所以我不能在不同的根状态上重用它们。

问题

有没有办法让两个商店在不同的应用程序中引用一些相同的选择器?

更新:我想出了一个我在下面发布的解决方案,但我愿意接受其他建议。谢谢!

【问题讨论】:

  • 可能是一个可以重复使用的附加元选择器? createMetaSelector = <T>() => createSelector<T, Tsomething>((store) => store.something)); const createSelectorA = createMetaSelector<RootStateA>()。类型安全是有代价的。
  • @estus 很好的建议和你对类型安全价格的权利:)

标签: angular ngrx


【解决方案1】:

好吧,我想我找到了办法。如果我为我让 RootState 实现的每个状态片创建一个接口,并在我的选择器中引用它,那么它似乎可以工作。以下是基本方法:

interface User {
  id: number;
  name: string
}

interface UsersSlice {
  users: User[];
}

const selectUsers = (state: UsersSlice) => state.users;

interface RootState extends UsersSlice {
}

class MyComponent {
  private data: Observable<User[]>;
  constructor(private store: Store<RootState>) {
    this.data = store.select(selectUsers);
  }
}

总体而言,该方法不会添加太多样板,因为无论如何您都必须定义 RootState。在这种方法中,您只需将其从“切片状态”中组合出来。然后你可以只引用你关心的粒度切片而不是世界。

如果你有很多选择器跨越不同的状态片,它可能会爆炸一点。如果您引用 RootState 那么它是不可移植的。您可以创建一个接口来扩展您想要的状态片段,如下所示:

interface Foo {
  id: number;
}
interface Bar {
  id: string;
}
interface FooBar {
  foo: Foo;
  bar: Bar;
}
interface FooSlice {
  foo: Foo;
}
interface BarSlice {
  bar: Bar;
}
const selectFoo = (state: FooSlice) => state.foo;
const selectBar = (state: BarSlice) => state.bar;
const selectFooBar = createSelector<FooBarSlice, Foo, Bar, FooBar>(
  selectFoo,
  selectBar,
  (foo: Foo, bar: Bar) => (<FooBar>{ foo, bar })
)
interface FooBarSlice extends FooSlice, BarSlice {}
interface RootSlice extends FooSlice, BarSlice, FooBarSlice {
  ...
}

因此,在最坏的情况下,您最终可能得到的接口数量等于所有可能的切片组合的数量。

更合理的选择是创建这样的临时交叉点 (FooSlice &amp; BarSlice):

const selectFooBar = createSelector<FooSlice & BarSlice, Foo, Bar, FooBar>(
  selectFoo,
  selectBar,
  (foo: Foo, bar: Bar) => (<FooBar>{ foo, bar })
)

对于特征切片中的状态,您必须按如下方式对其进行修改:

interface FeatureRoot extends FooSlice, BarSlice {}
const featureKey = 'feature';
interface FooState { 'feature': FooSlice; }
interface BarState { 'feature': BarSlice; }
type FeatureState = RootState & FooState & BarState;

const selectFeatureState = createFeatureSelector<FeatureRoot>(featureKey);
const selectFooState = createFeatureSelector<FooSlice>(featureKey);
const selectBarState = createFeatureSelector<BarSlice>(featureKey);

const selectFoo = createSelector(selectFooState, x => x.foo);
const selectBar = createSelector(selectBarState, x => x.bar);

class MyComponent {
  private foo: Observable<Foo>;
  private bar: Observable<Bar>;
  constructor(private store: Store<FeatureState>) {
    this.foo = store.select(selectFoo);
    this.bar = store.select(selectBar);
  }
}

【讨论】:

    猜你喜欢
    • 2016-11-02
    • 2021-05-17
    • 2021-02-09
    • 1970-01-01
    • 2021-09-07
    • 2010-11-12
    • 2011-11-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多