Angular,RxJs 服务存储 - 为什么 BehavioralSubject 比数组更适合存储数组数据?



在许多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();
}
}

希望这有帮助。

最新更新