Angular NGRX-调度动作时未调用效果

发布于 2025-02-10 19:45:57 字数 6357 浏览 2 评论 0原文

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"
  }
}

我是NGRX的新手,这是 对于商店,

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

export type AppState = {
  user: User;
};

这是src/store/action/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/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.ducers.ts定义了用于操作的还原器,我添加了控制台.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/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);

这是类型用户的接口(您需要)src/app/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/login.component.ts in Function Login in Function Login:

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);
  }
}

这就是我切换时得到的内容 的效果中看不到任何控制台。

如您所见,在浏览器上检查,还原器获得了正确的用户名和密码,但是从尚未称效果尚未称为

请帮助我,这意味着一个很多,谢谢你的时间,祝你有美好的一天

I am newbie with Ngrx and this is package.json file for my project, I am trying to implement dispatch login action for my project

{
  "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"
  }
}

this is src/store/index.ts for store

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

export type AppState = {
  user: User;
};

this is src/store/actions/user.action.ts for user 's actions

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 }>());

this is src/store/effects/user.effects.ts for actions when dispatching they will call, I add console.log to display username and password when it was passed:

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 }
  );
}

this is src/store/reducers/user.reducers.ts is defined the reducers for actions, I add console.log to display username and password:

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;
  })
);

this is the selectors 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);

this is the interface for type User (incase you need) 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;
}

the action is dispatch in src/app/pages/login/login.component.ts in function login:

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);
  }
}

and this is what I got when I toggle inspect on browser, as you can see, The reducer got correct username and password but It cannot see any console.log from the effect that the effects has not been called yet

enter image description here

please help me, it means a lot, thanks for your time and have a good day

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

烈酒灼喉 2025-02-17 19:45:57

问题起源于state.currentuser = {username,password};,在这里您尝试分配{username,password} ,但是currentuser在ngrx状态,此对象状态仅读取。

而是创建一个新操作,该动作在登录成功时会设置已登录的用户(可能结果?)。

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

Problem originates from state.currentUser = { username, password };, here you are trying to assign { username, password } but currentUser is in ngrx state, and this object state is read only.

Instead create a new action, which on login success, sets the logged in user (probably result?) somewhere in the state.

map((result) => {
              console.log("success", result);
    // create new action here OnLoginSuccess
            }),
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文