我开始学习使用NgRx库,在学习了如何通过调度保存状态并通过商店获取状态的基础知识之后,我开始着手尝试并理解和实现它,但并没有成功。
user.model
export interface User {
userID: number;
id: number;
title: string;
completed: boolean;
}
user.action
import { Action } from '@ngrx/store';
import { User } from '../models/user.model';
export const LOAD_USER = '[USER] Load';
export class LoadUser implements Action {
readonly type = LOAD_USER;
constructor(public payload: User) {}
}
export type Action = LoadUser;
user.reducer
import { User } from '../models/user.model';
import * as UserAction from '../actions/user.actions';
const initialState: User = {
userID: null,
id: null,
title: null,
completed: null
};
export function userReducer(state: User = initialState, action: UserAction.Action) {
switch (action.type) {
case UserAction.LOAD_USER:
return action.payload;
default:
return state;
}
}
app.state
import { Comment } from './models/comment.model';
import { User } from './models/user.model';
export interface AppState {
readonly comment: Comment[];
readonly counter: number;
readonly user: User[];
}
app.module
imports: [
BrowserModule,
HttpClientModule,
AppRoutingModule,
FormsModule,
ReactiveFormsModule,
StoreModule.forRoot({
comment: commentReducer,
counter: counterReducer,
user: userReducer
}),
EffectsModule.forRoot([UserEffect]),
StoreDevtoolsModule.instrument({
maxAge: 25, // Retains last 25 states
}),
],
user.efect
import { Injectable } from '@angular/core';
import { Actions, ofType, createEffect } from '@ngrx/effects';
import { EMPTY } from 'rxjs';
import { map, mergeMap, catchError } from 'rxjs/operators';
import { UserService } from '../core/services/user.service';
import * as UserAction from '../actions/user.actions';
@Injectable()
export class UserEffect {
$loadUser = createEffect(() => this.actions$.pipe(
ofType(UserAction.LOAD_USER),
mergeMap(() => this.userService.getUsers().pipe(
map((user) => new UserAction.LoadUser({userID: user[0].userID, id: user[0].id, title: user[0].title, completed: user[0].completed}))
)),
catchError(() => EMPTY)
));
constructor(
private actions$: Actions,
private userService: UserService
) {
}
}
user.service:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class UserService {
constructor(private http: HttpClient) { }
getUsers() {
return this.http.get('https://jsonplaceholder.typicode.com/todos/1');
}
}
我看着chrome dev-tool,似乎该事件没有触发。什么问题谢谢
当我尝试从组件调用动作/调度时 但是,这项工作不是完成了吗?参数我需要输入?
ngOnInit() {
this.store.dispatch(new UserActions.LoadUser({ userID: null, id: null, title: null, completed: null }))
}
答案 0 :(得分:0)
您将需要两种不同的操作,一种是LOAD_USER
来触发加载,另一种是例如USER_LOADED
从服务中携带用户信息并将其保存在减速器中。
这是您的操作的样子:
export const LOAD_USER = '[USER] Load';
export const USER_LOADED = '[USER] Loaded';
export class LoadUser implements Action {
readonly type = LOAD_USER; // no payload => no constructor needed
}
export class UserLoaded implements Action {
readonly type = USER_LOADED;
constructor(public payload: User) {}
}
您的减速器对这两种动作都有反应:
export function userReducer(state: User = initialState, action: UserAction.Action) {
switch (action.type) {
case UserAction.LOAD_USER:
return initialState; // reset user to default value while loading
case UserAction.USER_LOADED:
return action.payload;
default:
return state;
}
}
与您的效果略有不同:
$loadUser = createEffect(() => this.actions$.pipe(
ofType(UserAction.LOAD_USER),
mergeMap(() => this.userService.getUsers().pipe(
map(user => new UserAction.UserLoaded(user[0]))
)),
catchError(() => EMPTY)
));
在创建无穷循环时,效果的编写方式实际上可能导致内存泄漏-触发LoadUser时,将提取用户并触发LoadUser,这再次触发了效果...