简体   繁体   English

如何在新订阅中将所有值发布到观察者?

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

I have an observer that get different values published to it over time. 我有一个观察者,随着时间的流逝,它会获得不同的价值。 For example 例如

    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

If there is a subscription in #hack 1 it should get all values 1,2,3 and if there is subscription in #hack 2 it should get all values 1,2,3,4,5,6. 如果#hack 1中有一个预订,则应获取所有值1,2,3,如果#hack 2中有一个预订,则应获取所有值1,2,3,4,5,6。 Also, ReplaySubject gets old values, sure, but I want all the values on every publish. 另外,ReplaySubject当然可以获取旧值,但是我希望每次发布都具有所有值。 So, on every sub.next(7), I need all the values 1,2,3,4,5,6 and 7. So basically the observable stores all published or 'next'-ed values. 因此,在每个sub.next(7)上,我都需要所有值1,2、3、4、5、6和7。因此,基本上,可观的存储所有已发布或“下一个”编辑的值。 How do I achieve this? 我该如何实现?

Use BehaviorSubject with scan :) It's basically like Map.reduce, but emits on every update. 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);
  }
}

Live demo 现场演示

This line is what does all the magic: scan((acc, curr) => [...acc, curr]) It concats every value emitted by the subject into an array. 这行是所有魔术的作用: scan((acc, curr) => [...acc, curr])将主体发出的每个值组合成一个数组。

I like @TomaszKula's answer, but I think the question is about successive subscriptions picking up previous (and future) emits. 我喜欢@TomaszKula的答案,但我认为问题在于有关先前(以及将来)发出的连续订阅。

As far as I can tell, ReplaySubject does what is asked for... 据我所知, 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> 

The answer is: You can't with a simple Subject as you only have access to it's value inside a Subscription but never locally in your Service. 答案是:您不能使用简单的主题,因为您只能在订阅中访问它的值,而不能在服务中本地访问。 Using a BehaviorSubject you can. 您可以使用BehaviorSubject。

But first of all, make your subject private and accessible via methods only. 但首先,将您的主题设为私有并且只能通过方法访问。 Then you can do magic like this: 然后,您可以像这样做魔术:

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

}

And your Subscribers access this BehaviorSubject this way 您的订户以这种方式访问​​此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.

相关问题 如何在 PayPal 订阅 API 中获取用户的订阅状态 - How do I get the subscription status of a user in PayPal subscription API GraphQL-subscriptions:如何在订阅解析器中获取已发布的对象 - GraphQL-subscriptions: How to get published object in subscription resolver 如何使用 .get() 访问新的 Map() 键和值 - How do I access new Map() keys and values with .get() 如何从异步函数中获取数组的所有值 - How do I get all the values of an array from an async function 如何在角度中使用可观察和观察者? - How do I use observable and observer in angular? 聚合物 - 如何将观察者附加到数组? - Polymer - How do I attach an observer to an array? 如何循环遍历表中的图像,获取所有图像的src并应用于新表中的新图像? - How do I loop over images in table, get the src of ALL images and apply to new images in new table? 如何找到某个值并将其替换为新数组中的所有值? - How do I find a certain value and replace it in and push all the values in a new array? 如何获取在Meteor上的客户端的subscription方法上发布的数据? - How do I get the data published at client-side's subscribe method on Meteor? 我如何从数组中获取两个值并将它们包含在angularjs控制器中的新函数中 - How can I get two values from an array and include them in a new function all in an angularjs controller
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM