我不是专家,但这就是我理解 Observable 的方式,以及它们相对于简单数组的优势。
最终,我们希望一个值在模板发生变化时被动地更新自身,而无需手动检查。
类似这样的:
<div>{{ observableData$ | async }}</div>
observableData$ 变量是一个 Observable(由结尾 $ 的约定表示),它发送异步消息,可以使用 async 管道在模板中展开。
您的模板可以像使用简单数组一样轻松使用它。
例如。 <div>{{ [1, 2, 3] }}</div>
但 Observable 只是数据的流。
想象一条河流,它有一个定向的stream/水分子流。但是流更多的是动词而不是名词。
每条河流都需要一个源。水分子实际上来自哪里?
在rxjs 中,Observable 流 的“源”称为Subject。
Observable 不会“做”任何事情,只是提供从“源”/Subject 到您所在位置subscribing 到数据的管道。就像花园软管除了引导水流过它之外什么都不“做”。
现在,将BehaviorSubject 简单地视为具有指定初始值的Subject。
使用 BehaviouralSubject 有什么真正的好处?使用数组更容易..
使用BehaviorSubject 只是包含一个 Observable 流所需的几部分。
可观察的流是异步的,并且会像广播电台一样向“收听”或subscribed的任何人进行自我更新。
一个简单的数组显然有更简单的语法来存储和提取数据,但是一个数组不能在没有人工干预的情况下跨多个组件进行自我更新。这是 Observable 流的值。
此外,BehaviorSubject 是私有的,因为一开始就不需要任何外部的东西直接访问它。外部组件只需要访问 Observable 流,而不是 BehaviorSubject 本身。如果组件有权访问流,则源与组件无关。最好将其保密,并在同一服务中提供一个函数来更新 BehaviorSubject 的值(如果需要)。
例如..
在服务中:
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
@Injectable({ providedIn: 'root'})
export class ExampleService {
private exampleSource = new BehaviorSubject<any>(null);
example$: Observable<any> = this.exampleSource.asObservable();
updateSource(value: any) {
this.selectedDateSource.next(value);
}
}
我们定义了一个BehaviorSubject,初始值为null。
然后我们将example$ 定义为Observable(花园软管)以包含BehaviorSubject 发出的流。
函数可以更新BehaviorSubject 的.next() 值,此时example$ 将通过流传输新值,每个subscription 将被动地看到它的新值。
然后,在一个组件中:
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
@Component({
template: `
<div>{{ exampleData$ | async }}</div>
`,
})
export class ExampleComponent implements OnInit {
exampleData$: Observable<any>;
constructor(private exampleService: ExampleService) {}
ngOnInit() {
this.exampleData$ = this.exampleService.example$;
}
}
此外,您可以手动 subscribe 到组件中的 observable,但是还有更多步骤需要执行,您还必须手动 unsubscribe 到 observable。
此功能有效地包含在 Angular 的内置 async 管道中,用于上一个示例。
此组件示例产生与上一个示例相同的结果:
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Observable, Subscription } from 'rxjs';
@Component({
template: `
<div>{{ exampleData }}</div>
`,
})
export class ExampleComponent implements OnInit, OnDestroy {
exampleData: any;
exampleData$: Observable<any>;
exampleDataSubscription: Subscription;
constructor(private exampleService: ExampleService) {}
ngOnInit() {
this.exampleData$ = this.exampleService.example$;
this.exampleDataSubscription = this.exampleData$.subscribe(data => {
this.exampleData = data; // <-- your data from the BehaviorSubject
});
}
ngOnDestroy() {
this.exampleDataSubscription.unsubscribe();
}
}
希望这会有所帮助。