2017-08-16 79 views
0

我有几个子商店。比方说Sub1Sub2以下状态和减速器(行动并不是我的问题有趣......我猜的):ngrx/store 4:从商店选择时得到意外的子状态

Sub1的:

export interface Sub1State { 
    sub1value: string 
} 

export function sub1reducer(state: Sub1State, action: Action): Sub1State { 
    ... 
} 

分公司2:

export interface Sub2State { 
    sub2value: number 
} 

export function sub2reducer(state: Sub2State, action: Action): Sub2State { 

} 

然后我将这两个子状态合并为一个ActionReducerMap<ApplicationState>

export interface ApplicationState { 
    sub1: Sub1State, 
    sub2: Sub2State 
} 

export const reducers: ActionReducerMap<ApplicationState> = { 
    sub1: sub1reducer, 
    sub2: sub2reducer 
}; 

和“注册”它的商店:

StoreModule.forRoot(reducers) 

现在,在一个角度分量,我想选择Sub1店,并获得sub1value字符串。所以我做...

sub1value$: Observable<string>; 

constructor(private store: Store<Sub1State>) { 
    this.sub1value$ = store.map(state => { 
    console.log(state); 
    return state.sub1value; 
    }); 
} 

在日志中陈述,我希望得到以下对象(Sub1State对象):

{ 
    sub1value: 'initial value' 
} 

但我真正得到的是这个对象:

{ 
    sub1: { 
    sub1value: 'initial value' 
    } 
} 

这是按照预期工作吗?如果是的话,我应该如何使用接口Sub1State?因为sub1不是界面的一部分。

而且还好奇的是,呼吁state.sub1value什么显然是错误的,因为它必须是state.sub1.sub1value当我没有得到任何错误(没有编译器错误,也没有运行时错误)。没有运行时错误我明白,这是简单的未定义。但在我看来,TypeScript编译器应该在这里抛出一个错误。

我真的很困惑:/

编辑

这里是我怎么会想到一个例子它的工作原理:https://stackblitz.com/edit/angular-w34kua?file=app%2Fapp.component.ts

回答

0

当你的应用程序的状态,它返回一个对象。你的状态有两个子状态,它们被称为sub1和sub2。每一个都是它自己的对象。所以它按预期工作。你需要做'返回state.sub1.sub1value;

或者什么,我通常做的,就是我做这样的事情订阅特定减速,然后我只得到特定子状态回来,而不是整个状态:

constructor(private store: Store<Sub1State>) { 
    store.select('sub1').subscribe((state : Sub1State) => { 
    console.log(state); 
    this.sub1value$ = state.sub1value; 
    }); 
} 
+0

但如何再选择功能正常工作?我在大多数例子中看到了像'getValue1(state:Sub1State):string'这样的签名。但是,如果我将此选择器函数传递给'store.select(getValue1)',它将不起作用,因为传递给选择器函数的对象不是“Sub1State”类型,而是“sub1”根元素。另外一个具有子状态的商店被注入'构造函数(private store:Store )'。 –

+0

如果你按照我描述的方式做,你会得到sub1状态。做store.select('sub1')。订阅(.......)。这会给你sub1状态对象 – Kevin

+0

好吧,对,这是有效的。但如果我这样做,我也可以写一个简单的服务,我必须手动订阅和取消订阅。我失去了Flux/Redux/Store架构的一些很酷的功能。但我不想手动订阅和取消订阅,我只想分享应用程序状态并将其保存在本地可观察项中。以下是我期望能够工作的一个示例,但不起作用:https://stackblitz.com/edit/angular-w34kua?file=app%2Fapp.component.ts –