[英]NGRX | store.select(state => state.MyObject) | returns undefined
[英]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.