【问题标题】:Angular Binding Not Changing Before Observable CallAngular 绑定在 Observable 调用之前没有改变
【发布时间】:2018-09-29 01:55:35
【问题描述】:

我正在使用 Angular 4+,我注意到当 Observable 立即解析(同步?)时,Angular 在我调用 Observable.subscribe() 之前没有更新绑定值。 在其他地方这很好用,因为网络调用会延迟 Observable 完成足够长的时间,以使初始绑定更改在 Angular 中生效。

https://plnkr.co/edit/LV0On7?p=preview

//our root app component
import {Component, VERSION} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/delay';

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>{{name}}</h2>
      <button class="btn btn-primary" (click)="onAlertClickedNoDelay()">Call Observable Without Delay</button>
      <button class="btn btn-primary" (click)="onAlertClickedDelay()">Call Observable With Delay</button>

      <alert *ngIf="isAlertVisible()" type="success" dismissible="true" (onClose)="onAlertClose()">
          Async action successful!
      </alert>
    </div>
  `,
})
export class AppComponent {
  name:string;
  private isCallComplete = false;
  isAlertVisible(): boolean {
    console.log("isAlertVisible() binding updating: ", this.isCallComplete);
    return this.isCallComplete;
  }
  constructor() {
    this.name = `Angular! v${VERSION.full}`
  }

   onAlertClickedNoDelay() {
    this.isCallComplete = false;
    console.log("set isCallComplete = false");
    Observable.of("some data").subscribe(data => {
      this.isCallComplete = true;
      console.log("set isCallComplete = true");
    });
  }

   onAlertClickedDelay() {
    this.isCallComplete = false;
    console.log("set isCallComplete = false");
    Observable.of("some data").delay(0).subscribe(data => {
      this.isCallComplete = true;
      console.log("set isCallComplete = true");
    });
  }

  onAlertClose() {
    this.isCallComplete = false;
    console.log("set isCallComplete = false");
  }
}

没有 Observable.delay(),控制台打印:

设置 isCallComplete = false
设置 isCallComplete = true
isAlertVisible() 绑定更新:true
isAlertVisible() 绑定更新:true

使用 Observable.delay() 时,控制台正确打印:

设置 isCallComplete = false
isAlertVisible() 绑定更新:false
isAlertVisible() 绑定更新:false
设置 isCallComplete = true
isAlertVisible() 绑定更新:true
isAlertVisible() 绑定更新:true

1) 为什么 Angular 在使用 Observable.delay(0).subscribe() 而不是 Observable.subscribe() 时会检测到初始属性绑定(isCallComplete = false)?

2) 在调用 Observable.subscribe() 之前绑定到繁忙的属性值的最佳解决方案是什么?

【问题讨论】:

  • 您可以使用this answer 中建议的方法之一在订阅 observable 之前触发更改检测。
  • 谢谢,ChangeDetectorRef.detectChanges() 似乎是最好的解决方法。虽然我讨厌在使用 isBusy 属性的任何地方都这样做。

标签: javascript angular rxjs observable


【解决方案1】:

因为 Angular 从来没有机会检查 isCallComplete 的值。

Observable 的订阅回调在创建后立即执行。

使用delay(0) 等同于使用setTimeout(()=&gt;/*...*/,0),因此会在当前同步代码执行后延迟订阅回调的执行(在这种情况下,Angular 检查您的组件的值)

【讨论】:

  • 谢谢,因为这证实了我猜测的变化检测正在发生的事情。为了安全起见,我会在可观察调用之前手动让 Angular 知道属性更改。
猜你喜欢
  • 1970-01-01
  • 2018-10-31
  • 2020-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-07
  • 2017-05-26
相关资源
最近更新 更多