簡體   English   中英

NgRX存儲選擇返回存儲狀態而不是數據

[英]NgRX store select returns store state instead of data

我正在嘗試將ngrx v4實現到我的角度項目,並努力從ngrx商店獲取數據。 我在github頁面上根據提供的api文檔編寫了Actions,Reducer和Effects,在我看來一切都是正確的,但我得到的存儲狀態不是數據:

在此輸入圖像描述

如果有人能幫我弄清楚我的錯誤在哪里,我很感激。 提前致謝。 我的代碼如下

interface.ts

export interface Category {
  id?: number;
  name: string;
  used: boolean;
}

actions.ts

import { Action } from '@ngrx/store';
import {Category} from '../categories';

export const GET_CATEGORIES  = '[Category] Get data';
export const GET_CATEGORIES_ERROR = '[Category] Get data error';
export const GET_CATEGORIES_SUCCESS  = '[Category] Get data success ';

export class GetCategories implements Action {
  readonly type = GET_CATEGORIES;
}
export class GetCategoriesError implements Action {
  readonly type = GET_CATEGORIES_ERROR;
}
export class GetCategoriesSuccess implements Action {
  readonly type = GET_CATEGORIES_SUCCESS;
  constructor(public payload: Category[]) { }
}

export type All = GetCategories | GetCategoriesSuccess | GetCategoriesError

reducer.ts

import * as CategoriesActions from './categories.actions';
import {Category} from '../categories';

export type Action = CategoriesActions.All;

export function categoriesReducer (state: Category[], action: Action) {

  switch (action.type) {

    case CategoriesActions.GET_CATEGORIES: {
      return state;
    }

    case CategoriesActions.GET_CATEGORIES_ERROR: {
      return state;
    }

    case CategoriesActions.GET_CATEGORIES_SUCCESS: {
      return action.payload;
    }

    default: {
      return state;
    }
  }
}

effects.ts

...
import {CategoriesService} from './categories.service';

@Injectable()
export class CategoriesEffects {

  @Effect() getCategories$: Observable<Action> = this.actions$
    .ofType('GET_CATEGORIES')
    .mergeMap(action => this.categoriesService.getCategories()
      .map(data => ({type: 'GET_CATEGORIES_SUCCESS', payload: data }))
      .catch(() => of({ type: 'GET_CATEGORIES_ERROR', payload: {message: 'Oops something is wrong'} }))
    );

  constructor(
    private actions$: Actions,
    private categoriesService: CategoriesService
  ) {}
}

component.ts

interface CategoryState {
  categories: Category[]
}

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

export class CategoriesComponent implements OnInit {

  categories$: Observable<Category[]>;

  constructor(private store: Store<CategoryState>) {

    console.log(this.categories$) // undefined

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

    console.log(this.categories$) // store state
  }

  ngOnInit() {
    this.getCategories()
  }

  getCategories () {
    this.store.dispatch({ type: 'GET_CATEGORIES' });
  } 
}

@NgModule({
  imports: [
    ...
    StoreModule.forRoot({ categories: categoriesReducer }),
    EffectsModule.forRoot([CategoriesEffects]),
  ],
  declarations: [ CategoriesComponent ],
  providers:    [ CategoriesService ],
  entryComponents: []
})
export class CategoriesModule {}

這不是antonyboom特定問題的答案,而是對基於問題標題到達此處的其他人的有用提示:看來NGRX的Store.select將返回商店可觀察的默認值,以防它不能在您查詢的路徑中查找數據。 認為Apache 404錯誤。

我不得不修改我的類型轉換,以確保打字稿沒有強制執行不正確的商店結構。 具體來說,請注意,reducer中第一個參數的接口指定與注入組件的參數不同。

型號,減速機:

export interface AppState {
  textinput: string;
  integerVariable: number;
}
export interface State {
  app: AppState;
}

export function reducerFunction (
  state: AppState,
  action: Actions
) {
  switch (action.type) {
    ...
  }
}

app.module.ts:

StoreModule.forRoot({
  app: reducerFunction
})

app.component.ts

export class AppComponent {
constructor(private store: Store<State>) {
    this.currentSlide = store.select(s => s.app.textinput);
}
...
}

由於您使用的是ngrx/store : 4.1

  • 您應該有一個reducer工廠將Reducer注入StoreModule

     import {ActionReducerMap} from '@ngrx/store'; import {Category} from '../categories'; import * as categoryReducer from './categories.reducer'; export interface CategoryState { categories: Category[] } export interface AppStates { categoryState: CategoryState; } export const categoryReducers: ActionReducerMap<AppStates> = { categoryState: categoryReducer.reducer }; 
  • 使用reducer工廠注入模塊,如下所示,

     StoreModule.forRoot(categoryReducers) import {categoryReducers} from './store/categories.reducer.factory'; 
  • 您的構造函數應將AppStates作為Store的類型

     constructor(private store: Store<AppStates>){} 
  • 你應該使用效果

     @Effect() getCategories$: Observable<Action> = this.actions$ .ofType(CategoriesActions.GET_CATEGORIES) .mergeMap(action => this.categoriesService.getCategories() .map(data => ({type: CategoriesActions.GET_CATEGORIES_SUCCESS, payload: data })) .catch(() => of({ type: CategoriesActions.GET_CATEGORIES_ERROR, payload: {message: 'Oops something is wrong'} })) ); 

reducer導入部分中提供的名稱必須與State的參數名稱相同

商店:

export interface AppState {
  logs: string[];
}

export interface AppStore{
  appState: AppState; // (1)
}

app.module.ts導入:

StoreModule.forRoot({
  appState: reducerFunction // (2)
})

所以,(1)和(2)( appState )必須相同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM