angular - 从 Observables 订阅中获取更新的值

标签 angular observable

我注意到 Angular 2 中关于 Observables 的一些我无法解释的事情,希望好心人能为我解惑。

我的理解是,当订阅一个 Observable 时,您基本上有两种策略来消费它发出的值:

流与异步管道相结合,如:

myTextSubscription$ = SomeObservable.subscribe();

{{ myTextSubscription$ | async }}

或者提取值并从订阅处理程序中绑定(bind)它:

myTextSubscription$ = SomeObservable.subscribe(text => this.text = text);

{{ text }}

嗯,问题是我已经尝试过几次使用后一种方法,但我从未设法更新 text 值,除非我调用 this.cdRef。处理程序中的 markForCheck()。我想对于这样的基本场景不需要手动调用 changeDetection - 至少我没有看到在任何截屏视频或教程中使用过。

这听起来很熟悉吗?是我对方法的错误理解,还是 Angular 2 中的错误?


编辑:

上面的代码已经被抽象化了,因为我认为这个问题可以在更抽象的层面上得到解释。

我不记得第一个案例是什么时候它咬了我,但现在 Observable 来自 ngrx store,所以它基本上是这样的:

this.text$ = store.let((state$: Observable<State>) => {
  return state$.select(state => state.text);
});

最佳答案

事实上,您不应该在使用async 时订阅observable。 这就是为什么 async 如此棒。当您的组件初始化/销毁时,它会同时处理 subscribeunsubscribe

所以代替:
JS

myTextSubscription$ = SomeObservable.subscribe();

HTML

{{ myTextSubscription$ | async }}

你应该拥有:
JS

myTextSubscription$ = SomeObservable;

HTML

{{ myTextSubscription$ | async }}

我想澄清一下变量名中 $ 的用法:
- 可观察对象应以“$”作为后缀
- 当你使用 subscribe 时,你不会得到 observable

关于约定:
JS

let someObservable$ = ...;

HTML

{{ someObservable$ | async }}

请记住:
- 当您使用订阅时,您需要手动取消订阅,除了路由器和 http)
- 当你有一个 .subscribe 时,返回的值是 Subscription 类型(这意味着你可以取消订阅)

所以这是一个更清晰的结构(不使用异步管道)的概述:

@Component({
  selector: '...',
  templateUrl: '...html',
  styleUrls: ['...css']
})
export class AppComponent implements OnInit, OnDestroy {
    private myText: string;
    private myTextSubscription: Subscription;

    constructor() { }

    ngOnInit() {
        // I assume here that you declared an observable called "someObservable"

        this.myTextSubscription = someObservable$.subscribe(text => this.myText = text);
    }

    ngOnDestroy() {
        // as our observable is not coming from router or http, we need to manually
        // unsubscribe in order to avoid memory leaks

        this.myTextSubscription.unsubscribe();
    }

}

编辑 1: 在您更新的示例中,您应该如何将它与 @ngrx 一起使用:

@Component({
  selector: '...',
  templateUrl: '...html',
  styleUrls: ['...css']
})
export class AppComponent implements OnInit, OnDestroy {
  private text: string;
  private textSub: Subscription;

  constructor(private store$: Store<State>) {
    this.textSub =
        store$.select('yourState')
            .subscribe((state: State) => this.text = state);
  }

  ngOnDestroy() {
    this.textSub.unsubscribe();
  }
}

关于angular - 从 Observables 订阅中获取更新的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40398273/

相关文章:

mvvm - SwiftUI 使用高频数据更新 UI

javascript - JS、JQuery 和 Observable

angular - 输入类型 ="number"不能以 Angular 形式工作

javascript - 默认参数与问号

Angular 2 : How to use Observable filter

javascript - Angular 2 - 查看单个数据记录

Angular 2 - 在服务中设置超时

javascript - 将 Observables 实现到持久队列库中

swift - 在 RxSwift 中,我如何对一个可观察对象没有发送任何事件进行单元测试?

angular - 空订阅 Angular2 中的 valueChanges