在许多RxJs服务存储教程中(可能都是( - 行为主体用于在存储服务中存储数据。 例如这里: https://dev.to/avatsaev/simple-state-management-in-angular-with-only-services-and-rxjs-41p8
我想我会理解这个概念,如果我的应用程序中的某个地方我需要连接到我的数组数据。但是,就像在教程中一样,行为主题是私有的,我需要使用服务方法来获取它的价值,所以我不能只是订阅它。
我从使用行为主体中获得什么真正的好处?使用数组更容易。
存储数组数据的最佳方法是什么,这些数据来自 api,并在调用 api 时进行扩展?
它是通过流处理您的数据。在您的链接中,您可以看到他们正在使用 html 模板中的async
管道来循环todoStore.todo$
这实际上会导致订阅您的可观察量。
如果没有流(因此,如果它是一个普通数组(,即使您的 todoStoreService 更新了您的商店,您的 html 模板也不会更新,因为它不会收到更改数据的通知。
这就是我的理解,不确定它是否完全正确,但我认为这几乎就是这个例子中发生的事情。
我不是专家,但这就是我对可观察量的理解,以及它们相对于简单数组的优势。
最终,我们希望一个值在模板中被动更新,而无需手动检查它。
像这样:<div>{{ observableData$ | async }}</div>
observableData$
变量是一个 Observable(由结束$
的约定指示(,它发送异步消息,可以使用async
管道在模板中解包。
您的模板可以像使用简单的数组一样轻松地使用它.
eg。<div>{{ [1, 2, 3] }}</div>
但可观测只是数据流.>想想一条河流,它有一个定向流/水分子流。但流与其说是名词,不如说是一个动词。
每条河流都需要的是一个源头。水分子实际上起源于哪里?
在rxjs
中,可观测流的"源头"被称为Subject
。
可观察对象不会"做"任何事情,而是提供从您的"源"/Subject
到您subscribing
数据的任何地方的管道。就像花园软管不会"做"任何事情,而是引导流经它的水。
现在,将BehaviorSubject
简单地视为具有指定初始值的Subject
。
使用BehavioralSubject有什么真正的好处?使用数组更容易。
使用BehaviorSubject
只是包含可观察流所需的几部分中的一个。
可观察的流是异步的,并且像广播电台一样自行更新给"收听"或subscribed
的人。
一个简单的数组显然具有更简单的语法来存储和提取数据,但是如果没有手动干预,数组无法跨多个组件更新自身。这是可观察流的值。
此外,BehaviorSubject
是私有的,因为首先不需要直接访问任何外部内容。外部组件只需要访问可观察流,而不是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);
}
}
我们定义一个初始值为null
.
的BehaviorSubject
,然后我们将example$
定义为可观察(花园软管(,以包含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
组件中的可观察量,但是还需要执行一些步骤,并且还必须手动unsubscribe
到可观察量.
此功能有效地包含在 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();
}
}
希望这有帮助。