重用一个rxjs'跨多个功能的主题

时间:2018-05-10 03:04:16

标签: angular typescript rxjs

我有ApiClientService接收rxjs Service作为其所有方法中的参数之一。然后,此服务将API subscribe调用返回的Observable,解析返回值,然后回调Subject的{​​{1}}回调。< / p>

这个模型运行正常,直到在其中一个类中,让我们说next(),我有一个UserService用于调用多个API。在第二次API返回时,不会调用此Subject的{​​{1}}回调。我已经确认API确实返回了,它确实调用了Subject,传递了所需的值。

这是预期的行为吗? (每next()一项服务)或我的设计有问题吗?

提前致谢!

Service.next()

UserService.ts

Observable

使用// ApiClientService.ts @Injectable() export class ApiClientService { postUserLogin(userid: string, password: string): Observable<Object> { const url = "/api/getforuser"; const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json', }) } return this.http.post(url, { userid: userid }, httpOptions); } postSessionLogin(sessionid: string): Observable<Object> { const url = "/api/getforsession"; const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json', }) } return this.http.post(url, { sessionid: sessionid }, httpOptions); } }

的前端组件
// UserService.ts

@Injectable()
export class UserService {

  currentUser: UserModel;

  constructor(
    private apiclient: ApiClientService
  ) { }

  isLoggedIn(): boolean {
      if ( this.currentUser == null ) {
          return false;
      } else if ( this.currentUser.session != null ) {
          if ( this.currentUser.session.length > 0 ) {
              return true;
          }
      }
      return false;
  }

  sessionLogin(userListener: Subject<UserModel>) {
    console.log("UserService.sessionLogin");
    var session = this.cookieService.get("session");
    if ( session == null ) {
      userListener.error("session not found");
    } else {
      var obRes = this.apiclient.postSessionLogin(session);
      obRes.subscribe( res => {
        console.log("sessionLogin response");
        var payload = res['payload'];
        console.log("payload: " + payload);
        var user = payload['user'];
        console.log("user: " + user);
        this.currentUser = new UserModel;
        this.currentUser.userid = user.userid;
        userListener.next(this.currentUser);
      });
    }
  }

  userLogin(username: string, password: string, userListener: Subject<UserModel>) {
    console.log("UserService.userLogin start");
    var obRes = this.apiclient.postUserLogin(username, password);
    obRes.subscribe( res => {
      console.log("UserService.userLogin response start...");
      console.log(res);
      console.log("userLogin response json...");
      var payload = res['payload'];
      console.log("payload: " + payload);
      var user = payload['user'];
      console.log("UserService.userLogin user: " + user);
      this.currentUser = new UserModel;
      this.currentUser.userid = user.userid;
      userListener.next(this.currentUser);
    }, err => {
      console.log("not even error, nothing...");
      console.log(err);
    });
  }

}

1 个答案:

答案 0 :(得分:2)

我看不出问题的原因,但我可能会尝试给你一些建议。

为什么要使用主题?

为什么不直接将http客户端返回的Observable返回到您的组件,可能通过map运算符进行转换? 例如,这意味着像这样

sessionLogin() {
    console.log("UserService.sessionLogin");
    var session = this.cookieService.get("session");
    if ( session == null ) {
      Observable.throw("session not found");
    } else {
      return this.apiclient.postSessionLogin(session)
      .map( res => {
        console.log("sessionLogin response");
        return this.buildUser(res);
      });
    }
  }

userLogin(username: string, password: string) {
    console.log("UserService.userLogin start");
    return this.apiclient.postUserLogin(username, password)
    .map( res => {
      console.log("UserService.userLogin response start...");
      console.log(res);
      console.log("userLogin response json...");
      return this.buildUser(res);
    };
  }

buildUser(res) {
      const payload = res['payload'];
      console.log("payload: " + payload);
      const user = payload['user'];
      console.log("UserService.userLogin user: " + user);
      this.currentUser = new UserModel;
      this.currentUser.userid = user.userid;
      return this.currentUser;
}

然后您只需订阅sessionLogin或userLogin方法返回的Observable。

自动登录ngOnInit()

这是你的ngOnInit()方法的一部分

// try to login automatically
  this.userService.sessionLogin(this.loginListener);

  if ( this.userService.isLoggedIn() ) {
        console.log("user is logged in, todo: auto redirect");
        this.router.navigate(['/some/user/view']);
  }

您正在调用sessionLogin并立即检查是否有用户使用方法isLoggedIn登录。目前尚不清楚:如果用户已登录,则无需致电