1

前言

我们在平时用的某些组件传入的值为数组,组件只能检测数组长度变化,而数组的值发生变化时组件不能检测到变化,也就无法重新加载,这时可以使用Subject解决此类问题。

Subject

官方文档
Sbject是一种特殊的Observable,区别在于Subject可以将值传递给多个观察者,而Observable一般情况下是一对一的。Subject的作用是当我们需要告诉其他组件当前组件的值发生了变化时,可以通过Subject主动向外发送一个值,而需要感知这个组件值变化的组件就可以订阅这个值,通过这种方式感知组件发生变化,或在不同组件之间传值。

具体使用方法

下面以项目中的实例介绍具体用法
当前项目中需要两个组件,选择某一数据和选择全部数据组件, 要求当选择某一数据组件全被选中时,选择全部数据组件自动被选中,如果不全部选中,全部选择组件为未选中状态。由于选择全部数据组件传入的是数组,无法检测到值的变化。

v层代码

   <tr>
      <td>
        全选
        <app-check-all [singleChange$]="singleChange$" [checkboxes]="items" (beChange)="onAllChange($event)"></app-check-all>
      </td>
    </tr>
    <tr *ngFor="let object of items">
      <td>
        <app-check-single [checked]="object._checked"
                          (beChange)="onSingleChange($event, object)"></app-check-single>
      </td>
    </tr>

在父组件定义singleChangeSubject

singleChangeSubject = new Subject<void>();

选择某一数据组件的onSinglesChange()中通过singleChangeSubject发送一个null值

onSingleChange($event: boolean, object: Checkbox) {
    object._checked = $event;
    this.singleChangeSubject.next(null);
  }

注意:如果只想发送一次数据可以在执行完.next后执行.complete()

同样定义一个用于全部选择组件监听的Observable

singleChange$ = this.singleChangeSubject.asObservable();

singleChange$传入选择全部组件,在选择全部组件中订阅这个值就可以实现当选择某一数据组件值变化时选择全部组件可以检测到变化

this.singleChange$
      .subscribe(() => {
        // 数据变化后需要执行的操作
      })

Subject变体

BehaviorSubject

它有一个“当前值”的概念。它保存了发送给订阅者的最新值。并且当有新的观察者订阅时,会立即从 BehaviorSubject 那接收到“当前值”。

ReplaySubject

ReplaySubject 类似于 BehaviorSubject,它可以发送旧值给新的订阅者,但它还可以记录 Observable 执行的一部分。
ReplaySubject 记录 Observable 执行中的多个值并将其回放给新的订阅者。
当创建 ReplaySubject 时,你可以指定回放多少个值:

AsyncSubject

AsyncSubject 是另一个 Subject 变体,只有当 Observable 执行完成时(执行 complete()),它才会将执行的最后一个值发送给观察者。

Observable

Observable官方文档

Observable即可观察对象,可观察对象对在应用的各个部分之间传递消息提供了支持。
可观察对象是声明式的 —— 也就是说,虽然你定义了一个用于发布值的函数,但是在有消费者订阅它之前,这个函数并不会实际执行。 订阅之后,当这个函数执行完或取消订阅时,订阅者就会收到通知。
作为发布者,你创建一个 Observable 的实例,其中定义了一个订阅者(subscriber)函数。 当有消费者调用 subscribe() 方法时,这个函数就会执行。 订阅者函数用于定义“如何获取或生成那些要发布的值或消息”。
创建Observable

const observable = new Observable<string>(subscriber => {
  subscriber.next(1);
  subscriber.complete();
})

订阅

observable.subscribe(value =>{
})

总结

Subject是Observable的一种特殊形式,简单来说就是可以向外发送数据,并且可以被订阅,可以用于不同组件之间的传值。Observable与Subject不同在于Subject是多播的,当然,Observable也可以实现多播,但比较麻烦。Observable只有在被订阅后才会向外发送值,而Subject是主动向外传值。


李国稳
86 声望7 粉丝