【问题标题】:getValue from BehaviorSubject in Angular component从 Angular 组件中的 BehaviorSubject 获取值
【发布时间】:2020-04-29 18:36:57
【问题描述】:

我想尝试通过使用在我的组件中进行比较 如果(成功)显示消息 否则在 3 秒内重定向到页面。 但是,如果它发送 NULL,我如何检查这个 *(this.link$.source.value.success) 或 (this.link$.getValue()) *。我尝试在我的控制台浏览器中显示 this.link$,它显示的是 BehaivorSubject。我尝试使用 getValue() 方法,但它不起作用。你能帮帮我吗?

再次感谢

浏览器控制台.log

Service.ts

  private objectRes: BehaviorSubject<ResModel>;
  public activationOrResetResponse: Observable<ResModel>

  constructor(
    public _apiService: ApiService,
  ) {
    super(_apiService);

    this.objectRes = new BehaviorSubject(null) as BehaviorSubject<ResModel>;
    this.activationOrResetResponse = this.objectRes.asObservable();
  }

  public activateOrResetAccount(token: string, typeRoute: string): void {
    this._apiService.get(this.type + "/" + typeRoute + "/" + token).subscribe(
      (res) => {
        this.activationOrReset = res;
        this.objectRes.next(this.activationOrReset);
      },
      (error) => {
        this.activationOrReset = error;
        this.objectRes.next(this.activationOrReset);
      }
    );
  }

Component.ts

  public link$: Observable<ResModel>;
  constructor(
    private _authUserService: AuthUserService,
    private _activeRoute: ActivatedRoute,
  ) {}

  ngOnInit(): void {
    this.getActivationPage();
  }

  public getActivationPage(): void {
    this.link$ = this._authUserService.activationOrResetResponse;
    this._authUserService.activateOrResetAccount(
      this._activeRoute.snapshot.params.token,
      "confirmation"
    );
    console.log("link$: ", this.link$.getValue());   // null ???????
  }

【问题讨论】:

    标签: angular rxjs behaviorsubject


    【解决方案1】:

    我认为你得到了你的初始值,需要跳过它,直到从你的服务器得到响应。

    public getActivationPage(): void {
      this.link$ = this._authUserService.activationOrResetResponse;
      this._authUserService.activateOrResetAccount(
        this._activeRoute.snapshot.params.token,
        "confirmation"
      );
    
      this.link$
      .pipe( 
         skipWhile((value) => !value), // skip null values
         take(1) // if you need the value only once
      )
      .subscribe((res) => console.log(res));  // { "sucess": false, "message": "Bad action link!" }
    

    【讨论】:

    • @ValentynSHCHERBOV 我编辑了示例,请再次检查。
    【解决方案2】:

    value getter 是BehaviorSubject() 的一部分,而不是对应的 observable。所以你需要分配 BehaviorSubject() 而不是 observable 来使用它。试试下面的

    public getActivationPage(): void {
      this.link$ = this._authUserService.objectRes;  // <-- assign the `BehaviorSubject`
      this._authUserService.activateOrResetAccount(
        this._activeRoute.snapshot.params.token,
        "confirmation"
      );
      console.log("link$: ", this.link$.value);   // `value` instead of `getValue()`
    }
    

    而且它不起作用,因为该变量在服务中是私有的。

    我要补充一点,这看起来不太优雅。现在有两个不必要的BehaviorSubject 副本。更好的方法是在服务中编写一个吸气剂。 link$ 变量在我看来是多余的。

    服务

    private objectRes: BehaviorSubject<ResModel>;
    public activationOrResetResponse: Observable<ResModel>
    
    constructor(public _apiService: ApiService) {
      super(_apiService);
    
      this.objectRes = new BehaviorSubject(null) as BehaviorSubject<ResModel>;
      this.activationOrResetResponse = this.objectRes.asObservable();
    }
    
    get activationValue(): ResModel {
      return this.objectRes.value;
    }
    

    组件

      public getActivationPage(): void {
        this._authUserService.activateOrResetAccount(
          this._activeRoute.snapshot.params.token,
          "confirmation"
        );
        console.log("link$: ", this._authUserService.activationValue());
      }
    

    更新

    正确的做法是如下

    组件

      ngOnit() {
        this.getActivationPage();
        this._authUserService.activationOrResetResponse.subscribe(
          response => { console.log(response); }
        );
      }
    
      public getActivationPage(): void {
        this._authUserService.activateOrResetAccount(
          this._activeRoute.snapshot.params.token,
          "confirmation"
        );
      }
    

    【讨论】:

    • 我把一个变量 private 改成了 public 改了代码,但还是不行,concole 里有 NULL,为什么?
    • 因为服务中的activateOrResetAccount()是一个异步函数。在处理console.log() 时,该值尚未推送到BehaviorSubject。请参阅此处了解有关异步请求的更多信息:stackoverflow.com/a/14220323/6513921。这就是首先使用BehaviorSubject 的原因。使用value 是削弱它,它不会起作用。
    • 好的,谢谢,我明白了,我尝试设置 setTimeout 并且它工作正常,我在异步等待中更改了我的服务,再次感谢 :)
    • setTimeout() 在这种情况下也是一种解决方法。正确的方法是订阅 observable。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-07
    • 1970-01-01
    • 1970-01-01
    • 2020-03-08
    • 2018-10-27
    • 1970-01-01
    相关资源
    最近更新 更多