ngrx在应用之间共享状态

时间:2018-03-29 13:14:43

标签: angular ngrx

目标

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

问题

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

问题

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

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

1 个答案:

答案 0 :(得分: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。在这种方法中,您只需将其从&#34;切片状态&#34;中组合出来。然后你可以引用你关心的粒度切片而不是世界。

如果有很多选择器进入不同的状态切片,它可能会爆炸。如果您引用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 & 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);
  }
}