使BehaviorSubject Observable上的运算符无法正常工作

时间:2017-07-03 02:02:24

标签: angular rxjs

我有一个Angular应用程序,我试图将服务器下载的预订列表发送到Angular服务。我想让所有组件能够将预留数组作为可观察对象,并能够过滤和限制结果。现在我正在使用BehaviorSubject。这是我的代码。

//reservation.service.ts (partial code)

@Injectable()
export class TripService {
  public Trips: Object[] = [];
  public TripSubject: Subject<Object[]> = new BehaviorSubject<Object[]>([]);
  public trips$: Observable<Object[]> = this.TripSubject.asObservable();

  constructor(private apollo: Apollo) { 
    this.apollo.query({query: ReservationQuery}).subscribe((trips: any) => {
      this.Trips = trips.data.allReservations;      
      this.TripSubject.next(this.Trips)
    })
  }
}

//partial component

ngOnInit(): void {   
  this.tripService.trips$.take(3).subscribe(trips => {
    this.Trips = trips
  })
}

我得到了预订,但我得到了所有这些,而不仅仅是我想要使用take(3)。采用算子是否有效?

2 个答案:

答案 0 :(得分:2)

您的服务在一次next()调用中将整个阵列发送给主题。因此,ngOnInit()中的订阅者获取整个数组,而take(3)运算符不会执行任何操作,因为它将整个数组作为可观察流中的一个项接收。

答案 1 :(得分:2)

正如@Yakov Fain所说,你是在一个next()调用中将整个数组发送给主题。

如果您没有充分理由将对象数组转换为Observables数组,只需在数组中执行.slice()

ngOnInit(): void {   
  this.tripService.trips$.subscribe(trips => {
    this.Trips = trips.slice(0,3)
  })
}

否则,如果您真的想将其转换为一系列Observable(以便您可以使用.take(3)),那么您将需要使用.from()

ngOnInit(): void {
    this.tripService.trips$
        .switchMap(trips => Observable.from(trips));
        .take(3)
        .subscribe(trips=>{
            this.Trips = trips;
        });
}

请注意,获取一个Object数组和一个Observable数组的根本区别在于后者有多个事件发生。

区别在于:

使用.slice()

对一组对象进行单观察
const arr = [1, 2, 3, 4, 5];
const observables = Observable.of(arr);

observables
    .subscribe(x => {
        this.Trips = x.slice(0, 3)
        console.log(this.Trips);
    });
    //output: [1,2,3] 
    //this.Trips is an array of length 3.

使用.from()

从一组对象派生的多个Observable
const arr = [1, 2, 3, 4, 5];
const observables = Observable.from(arr);

observables
    .take(3)
    .subscribe(x => {
        this.Trips = x;
        console.log(this.Trips);
    });
    //output: 1
    //output: 2
    //output: 3
    //You got a single digit output, each are replaces the value of this.Trips on every emission.