Angular 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"
}
}
我是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
please help me, it means a lot, thanks for your time and have a good day
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题起源于
state.currentuser = {username,password};
,在这里您尝试分配{username,password}
,但是currentuser
在ngrx状态,此对象状态仅读取。而是创建一个新操作,该动作在登录成功时会设置已登录的用户(可能结果?)。
Problem originates from
state.currentUser = { username, password };
, here you are trying to assign{ username, password }
butcurrentUser
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.