角NgRx效果不会触发

时间:2019-12-11 16:36:01

标签: angular ngrx

我开始学习使用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 }))
  }

1 个答案:

答案 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,这再次触发了效果...