[英]How to Dispatch action which depends on Http method?
I am using NGXS
for state management in my angular application.我在我的 angular 应用程序中使用
NGXS
进行 state 管理。
Which one is a good practice?哪一个是好的做法?
For example, what is the process of user login using state management?比如用户使用state管理登录的流程是怎样的? Here, I have to make an HTTP call & then I have to do something depending on the response I get from the HTTP response.
在这里,我必须进行 HTTP 调用,然后我必须根据从 HTTP 响应中得到的响应来做一些事情。
Which one is good practice & why?哪一个是好的做法,为什么?
Also, please share example.另外,请分享示例。 Thanks in advance.
提前致谢。
Typical flow would look like so that LoginIn
action, triggers HTTP request authService.loginIn()
to validate credentials, successful response triggers LoginSuccess
, that action sets credentials to service/storage etc (isLoggedIn = true), components/services listening to state change react (or use authService to store logIn state);典型的流程看起来像这样
LoginIn
操作,触发 HTTP 请求authService.loginIn()
以验证凭据,成功响应触发LoginSuccess
,该操作将凭据设置为服务/存储等(isLoggedIn = true),组件/服务监听 Z9ED39E2EA931586B6A985A6942EF573E 更改反应(或使用 authService 存储登录状态);
LoginComponent.ts登录组件.ts
login() {
console.log(this.loginFrom.valid);
console.log(this.loginFrom.value);
this.store.dispatch(new Login(this.loginFrom.value));
}
AuthService.ts身份验证服务.ts
@Injectable({
providedIn: 'root',
})
export class AuthService {
private baseUrl = environment.apiUrl;
constructor(private _http: HttpClient) {}
loginIn(user: User) {
let { email, password } = user;
return this._http.post<User>(`${this.baseUrl}/login`, { email, password });
}
}
Effects.ts效果.ts
@Injectable()
export class AuthEffects {
@Effect()
LoginIn: Observable<any> = this.actions.pipe(
ofType(AuthActionTypes.LOGIN),
map((action: Login) => action.payload),
switchMap((payload) => {
return this.authService.loginIn(payload).pipe(
map((user: any) => {
return new LoginSuccess({ token: user.token, email: payload.email });
}),
catchError((error) => {
return of(new LoginFailure({ error }));
})
);
})
);
@Effect({ dispatch: false })
LoginSuccess: Observable<any> = this.actions.pipe(
ofType(AuthActionTypes.LOGIN_SUCCESS),
tap((user) => {
localStorage.setItem('token', user.payload.token);
this.router.navigate(['home']);
})
);
@Effect({ dispatch: false })
LogInFailure: Observable<any> = this.actions.pipe(
ofType(AuthActionTypes.LOGIN_ERROR)
);
@Effect({ dispatch: false })
LogOut: Observable<any> = this.actions.pipe(
ofType(AuthActionTypes.LOGOUT),
tap(() => {
localStorage.removeItem('token');
this.router.navigate(['login']);
})
);
constructor(
private actions: Actions,
private authService: AuthService,
private router: Router
) {}
}
Actions.ts动作.ts
export enum AuthActionTypes {
LOGIN = '[Auth] Login',
LOGIN_SUCCESS = '[Auth] SUCCESS',
LOGIN_ERROR = '[Auth] LOGIN_ERROR',
LOGOUT = '[Auth] Logout',
}
export class Login implements Action {
type = AuthActionTypes.LOGIN;
constructor(public payload: any) {}
}
export class LoginSuccess implements Action {
type = AuthActionTypes.LOGIN_SUCCESS;
constructor(public payload: any) {}
}
export class LoginFailure implements Action {
type = AuthActionTypes.LOGIN_ERROR;
constructor(public payload: any) {}
}
export class Logout implements Action {
type = AuthActionTypes.LOGOUT;
}
export type All = Login | LoginSuccess | LoginFailure | Logout;
Reducer.ts减速器.ts
export interface IState {
isAuthenticated: boolean;
user: User | null;
error: any;
}
export const initialState = {
isAuthenticated: false,
user: null,
error: null,
};
export function reducer(state = initialState, action: any): IState {
switch (action.type) {
case AuthActionTypes.LOGIN_SUCCESS: {
return {
...state,
isAuthenticated: true,
user: {
email: action.payload.email,
password: action.payload.password,
},
error: null,
};
}
case AuthActionTypes.LOGIN_ERROR: {
return {
...state,
error: 'Invalid User/Password',
};
}
case AuthActionTypes.LOGOUT: {
return initialState;
}
default: {
return state;
}
}
}
HomeComponent.ts主页组件.ts
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css'],
})
export class HomeComponent implements OnInit {
state$: Observable<any>;
isAuthenticated: boolean;
error: any;
user: User;
constructor(private store: Store<IAppState>) {
this.state$ = this.store.select((state) => state.auth);
}
ngOnInit() {
this.state$.subscribe((r: IState) => {
this.user = r.user;
this.error = r.error;
this.isAuthenticated = r.isAuthenticated;
});
}
logout() {
this.store.dispatch(new Logout());
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.