Angular 5订阅和取消订阅Observable

ghu*_*eur 3 observable rxjs typescript angular

我必须从两个订阅中获取数据,但我总是得到第一个的数据.

我有一个数据共享服务:

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


@Injectable()
export class DataService {

    private source = new BehaviorSubject<any>('');
    data = this.source.asObservable();

    constructor() { }

    update(values: any) {
        this.source.next(values);
    }
}
Run Code Online (Sandbox Code Playgroud)

在离开搜索组件之前,我调用了update方法.
现在,我在结果组件上.我得到这样的共享数据:

constructor(private dataSvc: DataService,
        private router: Router,
        private rideStore: RideStore) { }

    ngOnInit() {
        this.getData();
    }

    getData() {
        this.subscription = this.dataSvc.data.take(1).subscribe(
            data => this.data = data ? data : undefined,
            err => console.log(err),
            () => this._isValid()
        );
    } 
Run Code Online (Sandbox Code Playgroud)

我的问题是:我需要共享数据来订阅另一个observable.首先,我构建一个对象骑行并在我调用搜索方法之后

    search() {
    this.rideStore.searchRides(this.ride).subscribe(
        rides => {
            // this.dataSvc.update(rides);
            this.rides = rides;
            console.log('results', this.ride);
        },
        err => console.log('err', err)
    );
}
Run Code Online (Sandbox Code Playgroud)

问题是我总是从数据服务而不是从api调用获取数据.api工作导致我在存储中拦截结果但不在组件中拦截结果.那么如何才能停止订阅第一个可观察和订阅第二个?

小智 17

行为主题,订阅和取消订阅Observables

在多个组件中共享数据时,行为主体非常有用.您可以根据需要多次订阅它们.您也可以使用取消订阅方法取消订阅.

让我们采用上述服务并订阅该服务以获取数据:

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

@Injectable()
export class DataService {
    public source = new BehaviorSubject<any>(' ');
    data = this.source.asObservable();
    constructor() { }
    update(values: any) {
        this.source.next(values);
    }
}
Run Code Online (Sandbox Code Playgroud)

在这里,我已经声明了一个行为主题,其初始值为空字符串.请记住,您需要为行为主题提供默认值,无论是空字符串还是任何数字.之后,我使用asObservable()方法初始化了一个可观察的数据.最后,我创建了一个使用next()方法更新行为主题源值的方法.

现在,我将在组件中使用此服务从我们的行为主题中获取数据.

subscription: any;

constructor( private dataSvc: DataService ) {
    this.subscription = this.dataSvc.data.subscribe(
        data => console.log('Data:', data),
        err => console.log(err),
        () => console.log('complete')
    );
}
Run Code Online (Sandbox Code Playgroud)

在这里,我将DataService注入到组件中,并创建了该DataService dataSvc的实例.我已经使用dataSvc来调用我们的数据可观察并订阅该数据可观察以从我们的行为主题获取数据.因此,我将通过以下代码在浏览器控制台中获得的输出是:

Data: 
Run Code Online (Sandbox Code Playgroud)

所以我得到这个空,因为我使用空字符串作为我的行为主题的默认值.

现在要更新行为主题的值,我必须使用dataSvc服务的update方法,它将为空字符串将BehaviorSubject的值更新为新值.

//Insert this before subscribing the data observable
this.dataSvc.update('abc');

//Output in the console.
Data: abc
Run Code Online (Sandbox Code Playgroud)

现在该值已从空字符串更新为abc.这将反映在订阅此BehaviorSubject的每个组件中.

那么如果我想取消订阅此订阅该怎么办?所以我们必须将订阅初始化为

subscription: ISubscription;
Run Code Online (Sandbox Code Playgroud)

然后,每当我们想要取消订阅时,我们都会调用取消订阅的ISubscription方法

this.subscription.unsubscribe();
Run Code Online (Sandbox Code Playgroud)

因此,特定组件的完整代码将如下所示:

import { Component } from '@angular/core';
import { DataService } from "./data.service";
import {ISubscription} from "rxjs/Subscription";


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  subscription: ISubscription;

  constructor( private dataSvc: DataService ) {
    this.subscription = this.dataSvc.data.subscribe(
      data => console.log('Data:', data),
      err => console.log(err),
      () => console.log('complete')
    );
    this.dataSvc.update('abc');
    this.subscription.unsubscribe();
  }
}
Run Code Online (Sandbox Code Playgroud)