【问题标题】:BehaviorSubject is not updating when assigned data from api response从 api 响应分配数据时,BehaviorSubject 未更新
【发布时间】:2018-05-03 11:51:17
【问题描述】:

我有用户数据服务。数据服务的目的是广播用户数据并在不同组件之间共享数据。如果一个组件对用户进行了更改,其他组件应该知道它。它在其他组件中运行良好。例如,我在 Location 组件中更新了用户的位置,并且它随处可用。我有登录组件,我将用户凭据发送到 API 并接收用户数据。我将接收到的数据分配给我的广播用户对象,但它没有反映在我的结帐组件中。

user-data.service.ts

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

import {User} from '../entities/user';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class UserDataService {
  private _user: BehaviorSubject<User>;
  broadCastUser: Observable<User>;

  constructor() {
    this._user = new BehaviorSubject<User>(new User());
    this.broadCastUser = this._user.asObservable();
  }

  updateUser (newUser) {
    this._user.next(newUser);
  }
}

sign-in.component.ts

// removing unnecessary code
private _user: User;
ngOnInit() {

    // Getting user info so far
    this._userDataService.broadCastUser.subscribe(user => this._user = user);
}


signin () {
    const body = {
      UserId : this.emailAddress.value,
      Password : this.password.value
    };

    this._spinner.show();

    this._signInService.signIn(body).subscribe(
      (user) => {
        this._spinner.hide();

        // Handling error because API response is 200 Ok. Wrong API implementation.
        const userId = user[0].UserId;
        if (userId === 0) {
          this._isPasswordWrong = true;
        } else {
        this._user = user[0];
        this._user.isSignedIn = true;
        this._router.navigate(['/checkout']);
        }
      }
    );
  }

请注意登录方法 this._user = user[0]; 中的行。如果我在此行之后立即打印用户属性,那么我会看到它们已更新。但是当我去结帐组件时,它们没有更新。它们要么是旧值,要么是未定义的。

如果需要,我会提供所有代码。不过觉得这样就够了。

【问题讨论】:

  • 似乎您在 NgZone 之外调用了更新函数,因此 Angular 不会注册更改,也不会更新组件中的值。你从哪里调用更新?
  • @Leon 我没有在任何地方使用更新功能。本地对象链接到 BehaviorSubject 对象。它工作正常,没有应用程序中其他任何地方的更新功能。我会阅读有关 NgZone 的信息,看看是否可以修复它。

标签: angular http asynchronous behaviorsubject


【解决方案1】:

我不确定这是否是理想的解决方案,但该应用程序正在按照应有的方式运行。

我在 sign-in.component.ts 中添加了私有更新方法并在 signIn() 中调用它> 代替 this._user = user[0];

我从@Leon cmets 那里得到了提示,并得出了这个解决方案。

  signin () {
    const body = {
      UserId : this.emailAddress.value,
      Password : this.password.value
    };

    this._spinner.show();

    this._signInService.signIn(body).subscribe(
      (user) => {
        this._spinner.hide();

        // Handling error because API response is 200 Ok. Wrong API implementation.
        const userId = user[0].UserId;
        if (userId === 0) {
          this._isPasswordWrong = true;
        } else {
        this.updateUser (user[0]);
        this._router.navigate(['/checkout']);
        }
      }
    );
  }

新更新()

private updateUser (user: User) {
    let newUser = new User();
    newUser = user;
    newUser.cart = this._user.cart;
    newUser.address = this._user.address;
    newUser.isSignedIn = true;
    this._userDataService.updateUser(newUser);
  }

我愿意接受更好的答案。如果我找到了,我会在这里发布。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-29
    • 2019-10-11
    • 2021-11-06
    • 2018-06-28
    • 2018-09-22
    • 1970-01-01
    • 2021-12-31
    相关资源
    最近更新 更多