簡體   English   中英

如何在新訂閱中將所有值發布到觀察者?

[英]How do I get all values published to an Observer on new subscription?

我有一個觀察者,隨着時間的流逝,它會獲得不同的價值。 例如

    sub = new Subject<any>();
    sub.next(1); sub.next(2); sub.next(3);
    #hack 1
    sub.next(4); sub.next(5); sub.next(6);
    #hack 2

如果#hack 1中有一個預訂,則應獲取所有值1,2,3,如果#hack 2中有一個預訂,則應獲取所有值1,2,3,4,5,6。 另外,ReplaySubject當然可以獲取舊值,但是我希望每次發布都具有所有值。 因此,在每個sub.next(7)上,我都需要所有值1,2、3、4、5、6和7。因此,基本上,可觀的存儲所有已發布或“下一個”編輯的值。 我該如何實現?

BehaviorSubjectscan一起使用:)基本上類似於Map.reduce,但在每次更新時發出。

import { Component } from '@angular/core';

import { scan } from 'rxjs/operators';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

@Component({
  selector: 'my-app',
  template: `
  <input (keydown.enter)="onMessage(input.value); input.value =''" #input />

  <div *ngFor="let message of messages$ | async">
    {{ message }}
  </div>
  `,
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  private messagesSource = new BehaviorSubject<any>([]);
  messages$ = this.messagesSource.asObservable()
    .pipe(scan((acc, curr) => [...acc, curr], []));

  onMessage(val: string) {
    this.messagesSource.next(val);
  }
}

現場演示

這行是所有魔術的作用: scan((acc, curr) => [...acc, curr])將主體發出的每個值組合成一個數組。

我喜歡@TomaszKula的答案,但我認為問題在於有關先前(以及將來)發出的連續訂閱。

據我所知, ReplaySubject執行要求的操作...

 console.clear() const sub = new Rx.ReplaySubject(); sub.next(1); console.log('1st subscribe') sub.subscribe(x => console.log('1st', x)) sub.next(2); console.log('2nd subscribe') sub.subscribe(x => console.log('2nd', x)) sub.next(3) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.8/Rx.js"></script> 

答案是:您不能使用簡單的主題,因為您只能在訂閱中訪問它的值,而不能在服務中本地訪問。 您可以使用BehaviorSubject。

但首先,將您的主題設為私有並且只能通過方法訪問。 然后,您可以像這樣做魔術:

import { Injectable } from '@angular/core';
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
import {Observable} from 'rxjs/Observable';

@Injectable()
export class DataService {

   private subject = new BehaviorSubject<string>();

   setData(data: string) {
     this.subject.next(
       this.subject.getValue() + ',' + data;
     );
   }

   clearData() {
     this.subject.next();
   }

   getData(): Observable<any> {
      return this.subject.asObservable();
   }

}

您的訂戶以這種方式訪問​​此BehaviorSubject

constructor(private dataService:DataService){}

ngOnInit(): void {
   this.dataService.getData().subscribe(data => {
      // do something with data
   });
}

private aMethod(): void {
   this.dataService.setData(aString);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM