簡體   English   中英

Angular Ngrx - 調度動作時不調用效果

[英]Angular Ngrx - Effects not be called when dispatch Actions

我是 Ngrx 的新手,這是我項目的package.json文件,我正在嘗試為我的項目實現調度登錄操作

{
  "name": "shop-saleman",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^11.0.5",
    "@angular/common": "^11.0.5",
    "@angular/compiler": "^11.0.5",
    "@angular/core": "^11.0.5",
    "@angular/forms": "^11.0.5",
    "@angular/localize": "^11.0.5",
    "@angular/platform-browser": "^11.0.5",
    "@angular/platform-browser-dynamic": "^11.0.5",
    "@angular/router": "^11.0.5",
    "@ng-bootstrap/ng-bootstrap": "9.1.3",
    "@ngrx/effects": "^11.0.0",
    "@ngrx/store": "^11.0.0",
    "@types/socket.io-client": "^3.0.0",
    "bootstrap": "4.5.0",
    "ngx-cookie-service": "11.0.2",
    "pretty-ms": "^7.0.1",
    "rxjs": "^6.6.3",
    "rxjs-compat": "^6.0.0",
    "socket.io-client": "^4.5.1",
    "tslib": "^2.0.3",
    "zone.js": "^0.10.3"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^0.1100.4",
    "@angular/cli": "^11.0.4",
    "@angular/compiler-cli": "^11.0.5",
    "@types/jasmine": "~3.6.0",
    "@types/jasminewd2": "~2.0.3",
    "@types/node": "^12.19.9",
    "codelyzer": "^6.0.1",
    "jasmine-core": "~3.6.0",
    "jasmine-spec-reporter": "~5.0.0",
    "karma": "~5.1.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage": "~2.0.3",
    "karma-jasmine": "~4.0.0",
    "karma-jasmine-html-reporter": "^1.5.4",
    "protractor": "~7.0.0",
    "ts-node": "~8.3.0",
    "tslint": "~6.1.0",
    "typescript": "~4.0.2"
  }
}

這是存儲的src/store/index.ts

import { User } from "src/app/model/user.model";

export type AppState = {
  user: User;
};

這是用戶操作的src/store/actions/user.action.ts

import { createAction, props } from "@ngrx/store";
import { User } from "src/app/model/user.model";

export const Types = {
  LOGIN_PWD: "[USER] login with password",
  LOGIN_SUC: "[USER] login successfully",
  LOGIN_FAILED: "[USER] login failed",
};

export const lgPwd = createAction(
  Types.LOGIN_PWD,
  props<{ username: string; password: string }>()
);

export const lgSuc = createAction(
  Types.LOGIN_SUC,
  props<{ user: User; token: string }>()
);

export const lgFail = createAction(Types.LOGIN_FAILED, props<{ error: any }>());

這是src/store/effects/user.effects.ts用於調度他們將調用的操作,我添加 console.log 以在傳遞時顯示用戶名和密碼:

import { Actions, ofType, createEffect, Effect } from "@ngrx/effects";
import { Injectable } from "@angular/core";
import { Store } from "@ngrx/store";
import { AppState } from "..";
import { UserService } from "src/app/services/auth.service";
import { lgPwd } from "../actions/user.actions";
import { catchError, map, switchMap } from "rxjs/operators";
import { from } from "rxjs";

@Injectable()
export class UserEffect {
  constructor(
    private action: Actions,
    private store: Store<AppState>,
    private user_service: UserService
  ) {}

  lgPwdCall = createEffect(
    () => {
      return this.action.pipe(
        ofType(lgPwd),
        switchMap(({username, password}) => {
          console.log('EFFECT ->', username, password)
          return from(
            this.user_service.lgPwd(username, password)
          ).pipe(
            map((result) => {
              console.log("success", result);
            }),
            catchError((err): any => {
              console.log("err", err);
            })
          );
        })
      );
    },
    { dispatch: false }
  );
}

這是src/store/reducers/user.reducers.ts定義了動作的減速器,我添加了 console.log 來顯示用戶名和密碼:

import { createReducer, on } from "@ngrx/store";
import { lgPwd } from "../actions/user.actions";

const initialState = {
  currentUser: null,
  token: "",
};

export const userReducer = createReducer(
  initialState,
  on(lgPwd, (state, { username, password }) => {
    console.log("REDUCER ->", username, password);
    state.currentUser = { username, password };
    return state;
  })
);

這是選擇器src/store/selectors/user.selectors.ts

import { createSelector } from "@ngrx/store";
import { AppState } from "..";

export const userState = (state: AppState) => state.user;

export const selectCurrentUser = createSelector(userState, (user) => user);

這是 User 類型的接口(如果需要) src/app/model/user.model.ts

export interface User {
  addressList: string[];
  avatar: string;
  cardNumber: string;
  email: string;
  isActived: boolean;
  mediaList: Media[];
  phoneNumber: string;
  role: string;
  username: string;
  zipCode: string;
  _id: string;
}

export interface Media {
  _id: string;
  mimetype: string;
  filename: string;
}

該操作在函數登錄的src/app/pages/login/login.component.ts中調度:

import { Component, OnInit } from "@angular/core";
import { Router } from "@angular/router";
import { Store } from "@ngrx/store";
import { CookieService } from "ngx-cookie-service";
import { AppState } from "src/store";
import { lgPwd } from "src/store/actions/user.actions";
import { UserService } from "../../services/auth.service";

@Component({
  selector: "app-login",
  templateUrl: "./login.component.html",
  styleUrls: ["./login.component.scss"],
})
export class LoginComponent implements OnInit {
  email: string = "";
  pwd: string = "";
  isLogin: boolean = false;
  visiblePwd: boolean = false;

  constructor(
    private api: UserService,
    private route: Router,
    private cookie_service: CookieService,
    private store: Store<AppState>
  ) {}

  ngOnInit(): void {}

  login() {
    this.isLogin = true;
    this.store.dispatch(lgPwd({ username: this.email, password: this.pwd }));
  }

  togglePwd() {
    return (this.visiblePwd = !this.visiblePwd);
  }
}

這就是我在瀏覽器上切換檢查時得到的結果,如您所見,reducer 獲得了正確的用戶名和密碼,但它看不到任何 console.log,因為效果尚未被調用

在此處輸入圖像描述

請幫助我,這意味着很多,感謝您的寶貴時間,祝您有美好的一天

問題源於state.currentUser = { username, password }; , 在這里您嘗試分配{ username, password }currentUser處於 ngrx 狀態,並且此對象狀態是只讀的。

而是創建一個新操作,在登錄成功時,將登錄用戶(可能是結果?)設置為狀態中的某個位置。

map((result) => {
              console.log("success", result);
    // create new action here OnLoginSuccess
            }),

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM