我昨天开始学习ngrx。因此,为了一些实践,我决定用它重写我的组件。它曾经在没有ngrx的情况下工作得很好。我的showcase.component.ts:
@Component({
selector: 'app-showcase',
templateUrl: './showcase.component.html',
styleUrls: ['./showcase.component.css']
})
export class ShowcaseComponent implements OnInit {
books$ = this._store.pipe(select(selectShowcaseList));
constructor(private _store: Store<IAppState>) {
}
ngOnInit(): void {
this._store.dispatch(getBooks());
}
}showcase.effects.ts (我猜麻烦来了):
@Injectable()
export class ShowcaseEffects {
getBooks$ = createEffect(() => this.actions$.pipe(
ofType('[Showcase] getBooks'),
mergeMap(() => this.booksService.getBooks()
.pipe(
map(books => ({ type: '[Showcase API] BooksLoaded Success', payload: books })),
catchError(() => EMPTY)
))
)
);
constructor(
private actions$: Actions,
private booksService: BookService,
private _store: Store<IAppState>
) { }
}showcase.reducer.ts:
export const showcaseReducer = createReducer(
initialState,
on(showcaseActions.getBooksSuccess, (state, {books}) => ({ ...state, books: books})),
)showcase.actions.ts:
export const getBooks = createAction(
'[Showcase] getBooks'
)
export const getBooksSuccess = createAction(
'[Showcase API] BooksLoaded Success',
props<{books: Observable<Book[]>}>()
);showcase.state.ts:
export interface IShowCaseState {
books: Observable<Book[]>;
}
export const initialState: IShowCaseState = {
books: null
}showcase.selectors.ts:
export const selectShowcase = (state: IAppState) => state.showcase;
export const selectShowcaseList = createSelector(
selectShowcase,
(state: IShowCaseState) => state.books
);我的状态是:
export interface IAppState {
showcase: IShowCaseState;
test: ITestState;
}
export interface IShowCaseState {
books: Book[];
}
export const initialState: IShowCaseState = {
books: null
}app.module:
@NgModule({
declarations: [
AppComponent,
AuthenticationComponent,
ShowcaseComponent,
CartComponent,
AccountComponent,
CreateBookComponent,
TestComponent //ttt
],
imports: [
AngularFireModule.initializeApp(environment.firebase),
AngularFireDatabaseModule,
BrowserModule,
AppRoutingModule,
//запихнуть в отдельный модуль
StoreModule.forRoot({ books: fromShowcase.showcaseReducer, test: fromTest.testReducer }),
EffectsModule.forRoot([ShowcaseEffects]),
StoreDevtoolsModule.instrument({
maxAge: 10
}),
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }Console告诉我变量book$是未定义的。对于我的目的,我还没有找到使用新的NGRX 9.X语法的好例子。如果你有任何NGRX 9.X应用程序的例子,其中使用了数据获取服务的效果,请给我一个链接。
发布于 2020-04-14 06:11:55
你在有效载荷上发送了错误的数据。reducer期望的是一个具有books属性的对象,但它得到的却是一个图书数组。你可以通过稍微改变你的效果来修复它:
import * as fromActions from '...showcase.actions'
...
getBooks$ = createEffect(() => this.actions$.pipe(
ofType(fromActions.getBooks),
// instead of returning an empty operator in catchError, let's return an empty array
switchMap(() => this.booksService.getBooks().pipe(catchError(() => of([])))),
// the main problem in your code was this "payload: books"; use, instead, "payload: {books}"
map(books => fromActions.getBooksSuccess({books})),
));让我们来修复您的getBoosSuccess操作
export const getBooksSuccess = createAction(
'[Showcase API] BooksLoaded Success',
props<{books: Book[]}>()
);另外,修复你的状态:
export interface IShowCaseState {
books: Book[];
}
export const initialState: IShowCaseState = {
books: []
}我已经把一些东西组合在一起了on stackblitz。
https://stackoverflow.com/questions/61194460
复制相似问题