使用ngrx store 4

时间:2017-08-27 10:10:14

标签: angular ngrx ngrx-store ngrx-effects

在我的angular(4)app中,我想用ngrx 4介绍一个reducer / state management。

我有一个主模块

@NgModule({
    imports: [
        // ...
        StoreModule.forRoot({}),
        EffectsModule.forRoot([])
    ],

    declarations: [
        AppComponent
    ],

    bootstrap: [AppComponent]
})

和一个带有

的延迟加载模块
@NgModule({
    imports: [
        StoreModule.forFeature('lazy', {
            items: itemsReducer
        }),
        EffectsModule.forFeature([ItemEffects])
    ],

    declarations: [
        // Components & Directives
    ]
})

这是我的减速机

export function itemsReducer(state: Item[] = [], action: ItemAction<any>) {
    switch (action.type) {

        case ADD:
            return [action.payload, ...state];

        case DELETE:
            return state.filter((item) => item.id !== action.payload.id);

        case ITEMS_LOADED:
            return Object.assign([], action.payload);

        case LOAD_ITEMS:
            return state;

        default:
            return state;
    }
}

我也在处理这样的效果:

@Injectable()
export class ItemEffects {

    @Effect() addItem$: Observable<Action> = this.actions$.ofType(ADD)
        .mergeMap((payload: any) =>
            this.dataService.addItem(payload)
                // If successful, dispatch success action with result
                .map((data: any) => {
                    return createLoadItemsAction();
                })
                // If request fails, dispatch failed action
                .catch(() => of({ type: 'FAILED' }))
        );

    @Effect() loadItems$: Observable<Action> = this.actions$.ofType(LOAD_ITEMS)
        .mergeMap(() =>
            this.dataService.getAllItems()
                // If successful, dispatch success action with result
                .map((data: Item[]) => (createItemsLoadedAction(data)))
                // If request fails, dispatch failed action
                .catch(() => of({ type: 'FAILED' }))
        );

    constructor(
        private dataService: DataService,
        private actions$: Actions
    ) { }
}

在我的有状态组件中,我正在订阅此商店

export class MainItemsComponent implements OnInit {
    items: Observable<Items[]>;

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

    ngOnInit() {
        this.store.dispatch(createLoadItemsAction());
    }

    // ...

}

使用console.logs我可以看到效果正常,使用正确的操作“ITEMS_LOADED”调用reducer,所有项都在里面,但它们没有传递给我的有状态组件而且没有显示。 / p>

我的行为看起来像这样

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

export interface ItemAction<T> extends Action {
    payload?: T;
}

/*
 * action types
 */

export const ADD = 'ADD'
export const DELETE = 'DELETE'
export const LOAD_ITEMS = 'LOAD_ITEMS'
export const ITEMS_LOADED = 'ITEMS_LOADED'

/*
 * action creators
 */

export function createAddItemAction(item: Item): ItemAction<Item> {
    return { type: ADD, payload: item }
}

export function createDeleteItemAction(item: Item): ItemAction<Item> {
    return { type: DELETE, payload: item }
}

export function createItemsLoadedAction(items: Item[]): ItemAction<Item[]> {
    return { type: ITEMS_LOADED, payload: items }
}

export function createLoadItemsAction(): ItemAction<Item> {
    return { type: LOAD_ITEMS }
}

我正在使用

 "@ngrx/effects": "^4.0.5",
 "@ngrx/store": "^4.0.3",

我错过了什么?我的目标是在加载组件时加载项目。

3 个答案:

答案 0 :(得分:1)

嗯。如果我理解正确,选择另一种方式。

你现在期待什么? this.store.select('items')这应该如何运作?

据我所知,你需要创建选择器。我不确定你是否创建了它们,因为我在你提供的代码中看不到它们中的任何一个。而且你也以一种奇怪的方式使用select

我认为,你错过了选择者。你需要这个:

  • 创建选择器的示例:here
  • 使用选择器的示例:here

或者,您能解释一下您对当前代码的期望吗? :)也许我不知道什么。

答案 1 :(得分:0)

尝试定义AppState接口并键入商店的状态:

interface AppState{
  items: Item[]
}

constructor(private store: Store<AppState>)

然后不要忘记模板文件中的异步管道(items | async)或在组件文件中订阅(但我想你知道)

答案 2 :(得分:0)

要获取数据,您需要使用选择器并添加A. Moynet上面提到的状态

https://ngrx.io/guide/store/selectors

ngrx的例子是

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

export interface FeatureState {
  counter: number;
}

export interface AppState {
  feature: FeatureState;
}

export const selectFeature = (state: AppState) => state.feature;

export const selectFeatureCount = createSelector(
  selectFeature,
  (state: FeatureState) => state.counter
);

要使用此功能,我们将在组件中执行

ngOnInit() {
    this.counter = this.store.pipe(select(fromRoot.selectFeatureCount))
}
相关问题