我必须从两个订阅中获取数据,但我总是得到第一个的数据。
我有一个数据共享服务:
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);
}
}
在离开搜索组件之前,我调用了更新方法 现在,我在结果组件上。我得到这样的共享数据:
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()
);
}
我的问题是:我需要共享数据来订阅另一个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)
);
}
问题是我总是从数据服务而不是从api调用获取数据。 api工作导致我在存储中拦截结果但不在组件中拦截结果。那么我如何才能停止订阅第一个可观察和订阅第二个?
答案 0 :(得分:14)
Behavior subjects are very useful while sharing data in multiple components. You can subscribe them as many times as you want. Also you can unsubscribe it using unsubscribe method.
Let's take the above service and subscribe that service to get data:
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);
}
}
Here, I have declared a behavior subject with initial value empty string. Just remember that you need to give a default value to your behavior subject whether it a blank string or any number. After that, I have initialized an observable data using asObservable() method. And finally, I have created a method which updates the behavior subject source value using next() method.
Now I will use this Service in our component to get data from our behavior subject.
subscription: any;
constructor( private dataSvc: DataService ) {
this.subscription = this.dataSvc.data.subscribe(
data => console.log('Data:', data),
err => console.log(err),
() => console.log('complete')
);
}
Here I have injected our DataService to our component and I have created an instance of that DataService dataSvc. I have used dataSvc to call our data observable and subscribe that data observable to get data from our behavior subject. So the output which I will get in the browser console by the following code is:
Data:
So I am getting this empty because I have used an empty string as the default value for my behavior subject.
Now to update the value of behavior subject, I have to use update method of dataSvc service which will update the value of BehaviorSubject for the empty string to the new value.
//Insert this before subscribing the data observable
this.dataSvc.update('abc');
//Output in the console.
Data: abc
Now the value has been updated from empty string to abc. And this will reflect in each and every component where are subscribing this BehaviorSubject.
So what if I want to unsubscribe this subscription. So we have to initialize subscription as
subscription: ISubscription;
and then whenever we want to unsubscribe we will call unsubscribe method of ISubscription like this
this.subscription.unsubscribe();
So the complete code for a particular component will be like this:
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();
}
}