试图了解@ngrx select和AppState

时间:2017-10-09 15:49:07

标签: angular ngrx ngrx-store

我目前正在努力了解@ ngrx / store库的select命令是如何工作的。

我们有以下代码示例:

export interface AppState {
  message: string;
  messages: string[];
}

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {

  message$: Observable<string>;

  constructor(private store: Store<any>) {
    this.message$ = store.select<string>('message');
  }
}

我的减速机看起来像这样

import { Action } from '@ngrx/store';

export interface AppState {
  message: string;
  messages: string[];
}

export const initialState: AppState = {
  message: 'Hello World',
  messages: ['One', 'Two', 'Three']
};

export function messageReducer(state = initialState, action: Action) {
  switch (action.type) {
    case 'SPANISH':
      return Object.assign({}, state, {message: 'Hola Mundo'});
    case 'FRENCH':
      return Object.assign({}, state, {message: 'Bonjour le monde'});
    case 'GERMAN':
      return Object.assign({}, state, {message: 'Hello World'});
    default:
      return state;
  }
}

export function messagesReducer(state = initialState, action: Action) {
  switch (action.type) {
    case 'SPANISH':
      return Object.assign({}, state, {message: 'Hola Mundo'});
    case 'FRENCH':
      return Object.assign({}, state, {message: 'Bonjour le monde'});
    case 'GERMAN':
      return Object.assign({}, state, {message: 'Hello World'});
    default:
      return state;
  }
}

我的模板看起来像那样:

<div class="container-fluid">
  {{ (message$ | async) }}
  <button (click)="getGermanMessage()">Deutsche Version</button>
  <button (click)="getSpanishMessage()">Spanische Version</button>
  <button (click)="getFrenchMessage()">Französische Version</button>
  <router-outlet></router-outlet>
</div>

所以我的误解来自这条线

this.message$ = this.store.select('message');

我以为我会得到一个字符串类型的Observable,可以在我的模板中使用:

{{ message$ | async }}

我将得到商店中存在的价值,但据我所知,我得到一个对象,我必须选择特定的属性,但是&#39;消息&#39;如果不选择商店的请求属性,字符串在该行中?好像我对某些部分缺乏了解,但我不知道自己错过了什么。

所以我在模板中得到的是

[object Object]

这就是我的商店看起来像: https://imgur.com/a/UQgIX

也许这会让它更清晰。我没有t understand why i don从state.message这样的商店中获取消息值的可观察值,但当我这样做时,将状态本身作为对象:

this.message$ = this.store.select('message');

任何帮助都是适当的

2 个答案:

答案 0 :(得分:1)

AppState的每个属性都应该有一个reducer:

<强> app.module.ts

StoreModule.provideStore(
  { 
      message: messageReducer, 
      messages: messagesReducer
  })

应用-state.ts

export interface AppState {
    message: string,
    messages: string[]    
}

<强> messageReducer.ts

export function simpleReducer(state = '', action: Action) {
    ...
    return state;
}

<强> component.ts

在任何组件中,您可以订阅对AppState的任何属性(或子属性)的任何更改:

constructor(private store: Store<AppState>) {
  this.message$ = store.select<string>("message");
  this.messages$ = store.select<string[]>("messages")
}

我不确定你是否想要一个或两个减速器。基于你的AppState(应该包含整个应用程序的每个reducer的属性),我假设你想要两个。

select是一个rxjs select,它也是地图的别名 - 没什么特别的。

答案 1 :(得分:0)

我终于解决了我的误会。感谢pixelbits的帮助。我现在做的是在消息reducer中返回一个字符串而不是状态对象,所以我会得到一个字符串而不是状态对象

export function messageReducer(state: string = 'Hello World', action: Action) {
  switch (action.type) {
    case 'SPANISH':
      return 'Hola Mundo';
    case 'FRENCH':
      return 'Bonjour le monde';
    case 'GERMAN':
      return 'Hello World';
    default:
      return state;
  }
}

而不是

export function messagesReducer(state = initialState, action: Action) {
  switch (action.type) {
    case 'SPANISH':
      return Object.assign({}, state, {message: 'Hola Mundo'});
    case 'FRENCH':
      return Object.assign({}, state, {message: 'Bonjour le monde'});
    case 'GERMAN':
      return Object.assign({}, state, {message: 'Hello World'});
    default:
      return state;
  }
}