试图了解@ngrx select 和 AppState

Trying to understand @ngrx select and AppState

我目前正在努力了解@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 }}

我会得到商店中存在的值,但据我所知,我得到一个对象,我必须 select 特定属性,但是 'message' 字符串如果不是 select 存储请求的 属性 则在该行中做什么?好像我对某些部分缺乏了解,但我不知道我缺少什么。

所以我在模板中得到的是

[object Object]

这是我的商店的样子: https://imgur.com/a/UQgIX

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

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

任何帮助都适用

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

app.module.ts

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

app-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,它也是 map 的别名 - 没什么特别的。

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

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;
  }
}