首页 > 解决方案 > 无限循环角 NGXS 调度

问题描述

我得到一个无限循环代码......当这个组件正在加载时......知道如何停止这个......?

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Select, Store } from '@ngxs/store';
import { Observable } from 'rxjs';
import { UserProfile } from 'src/app/core/interfaces/userProfile';
import { GetUser } from './state/profile.action';
import { ProfileState } from './state/profile.state';

@Component({
  selector: 'app-profile',
  templateUrl: './profile.component.html',
  styleUrls: ['./profile.component.css']
})

export class ProfileComponent implements OnInit {
  @Select(ProfileState.userProfile) userProfile$!: Observable<UserProfile>;
  userId! :number;

  constructor(private store:Store,private router:Router) {}

  ngOnInit() {
    this.userProfile$.subscribe(userProfileData => {
      this.userId = userProfileData.id
      this.store.dispatch(new GetUser(this.userId));
        this.router.navigate(['/profile']);
       });
  }
 }

这是服务

import { Injectable } from '@angular/core';
import { HttpClient,  } from '@angular/common/http';
import { UserProfile } from 'src/app/core/interfaces/userProfile';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})

export class UserService {
  constructor(private httpClient: HttpClient) { }

  private USER_PROFILE = 'http://localhost:8080/api/user/userProfile/';

  getUser(id:number):Observable<UserProfile>{
    return this.httpClient.get<UserProfile>(this.USER_PROFILE + id);
  }

}

和州代码


import {Action, Selector, State, StateContext} from '@ngxs/store';
import { Login, Logout} from './auth.action';
import { LoginService } from '../login.service';
import { tap } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { Roles } from 'src/app/core/interfaces/role';
import { User } from 'src/app/core/interfaces/user';


export class AuthStateModel {
  accessToken: string | undefined;
      loggedInUser: User|undefined;
      username: string | undefined;
      email:string|undefined;
      roles:string |undefined;
      id: number |undefined;

}
@State<AuthStateModel>({
  name: 'auth',
  defaults: {
    loggedInUser:undefined,
    accessToken: undefined,
    username: undefined,
    email:undefined,
    roles:undefined,
    id: undefined

  }
})
@Injectable()
export class AuthState {
  result: null;

  @Selector()
  static isAuthenticated(state: AuthStateModel): boolean {
    return !!state.accessToken;
  }
  @Selector()
  static loggedInUser(state: AuthStateModel) {
    return state.loggedInUser;
  }
  @Selector()
  static role(state: AuthStateModel) {
    return state.roles;
  }
  @Selector()
  static getToken(state: AuthStateModel) {
    return state.accessToken;
  }
  @Selector()
  static loggedInUserName(state: AuthStateModel) {
    return state.username;
  }
  constructor(private loginService: LoginService) {}

  @Action(Login)
  login(ctx: StateContext<AuthStateModel>, action: Login) {
    return this.loginService.login(action.payload.username, action.payload.password).pipe(
      tap((result: { accessToken: string, username:string,email:string,roles:Roles,loggedInUser:string,id:number, password:string, name:string, token:string}) => {
      ctx.patchState({loggedInUser:result});
      window.localStorage.setItem('token',result.accessToken)
      window.localStorage.setItem('username',result.username)
      window.localStorage.setItem('email',result.email)
      window.localStorage.setItem('roles',result.roles)
      window.localStorage.setItem('id',result.id.toString())
    })
  );
  }

@Action(Logout)
logout(ctx: StateContext<AuthStateModel>) {
 this.loginService.logout()
    const state = ctx.getState();
      ctx.setState({...state,
          loggedInUser:undefined,
          accessToken: undefined,
          username: undefined,
          email:undefined,
          roles:undefined,
        });
        return state;
 };

}

**和另一个州**

import { Injectable } from "@angular/core";
import { Action, Selector, State, StateContext } from "@ngxs/store";
import { tap } from "rxjs/operators";
import { UserProfile } from "src/app/core/interfaces/userProfile";
import { UserService } from "../user.service";
import { GetUser } from "./profile.action";

export class ProfileStateModel {
  userProfile: UserProfile|undefined;
}

@State<ProfileStateModel>({
  name: 'profile',
  defaults: {
    userProfile:undefined,
  }
})
@Injectable()
export class ProfileState {
  profile!: UserProfile;

@Selector()
static userProfile(state: ProfileStateModel) {
  return state.userProfile;
}
constructor(private userService: UserService) {}

@Action(GetUser)
getUser(ctx: StateContext<ProfileStateModel>, action: GetUser ){
  const state = ctx.getState();
  return this.userService.getUser(action.payload).pipe(
      tap((result) => {
        ctx.setState({
          ...state,
          userProfile:result
        });
      })
  );
  }
}

好的,所以我试图从已调度的 auth.state 中获取 ID.. 并将 id 作为参数传递以进行 http 调用并获取 userProfile 数据,但我在无限循环中得到堆栈....我不知道这是否是一种正确的方法,或者它是代码的好习惯......但这是我认为这可能是我的 api 和前端项目的最佳方式......任何想法?

标签: angulartypescriptngrxngxs

解决方案


import { Router } from '@angular/router';
import { Select, Store } from '@ngxs/store';
import { Observable } from 'rxjs';
import { UserProfile } from 'src/app/core/interfaces/userProfile';
import { GetUser } from './state/profile.action';
import { ProfileState } from './state/profile.state';

@Component({
  selector: 'app-profile',
  templateUrl: './profile.component.html',
  styleUrls: ['./profile.component.css']
})

export class ProfileComponent implements OnInit {
  @Select(ProfileState.userProfile) userProfile$!: Observable<UserProfile>;
  userId! :number;
  constructor(private store:Store,private router:Router) {}

  ngOnInit() {
    this.userProfile$.subscribe(userProfileData => {
      this.userId = userProfileData.id});
  }
  getUserProfile(){
    this.store.dispatch(new GetUser(this.userId));
    this.router.navigate(['/profile']);
  }

 }

所以我认为它更简单......我只是用这个替换了代码......无论如何谢谢


推荐阅读