我的服务充当数据存储(简单关联数组)。有多个组件对这些数据感兴趣 - 每个组件都需要一个或多个键下的值,但他们从不想要整个事物。存储服务还会侦听外部事件,并通过重新计算数组中的所有值来对其做出反应。我正在尝试使用rxjs Observables实现整个事情。
我读到Observables为每个观察者分别执行他们的subsicribe()函数。这听起来就像我需要的那样,但我无法弄清楚:
next()
,但这会通过所有Observable发送相同的数据。以下是我现在所拥有的简化版本:
storage.service.ts
import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs/Rx';
@Injectable()
export class StorageService {
externalEvent = Observable.interval(2500);
data = {};
output = new Subject();
constructor() {
this.externalEvent.subscribe(n => {
this.data = {"a": Math.random(), "b": Math.random(), "c": Math.random()};
this.output.next(this.data);
});
}
}
app.component.ts
import { Component } from '@angular/core';
import { StorageService } from './storage.service';
@Component({
selector: 'app-root',
template: `
<app-child [param]="'a'"></app-child>
<app-child [param]="'b'"></app-child>
`,
providers: [StorageService]
})
export class AppComponent { }
child.component.ts
import { Component, OnInit, Input } from '@angular/core';
import { StorageService } from './storage.service';
@Component({
selector: 'app-child',
template: `
<p>{{ data }}</p>
`
})
export class ChildComponent implements OnInit {
@Input() param: string;
data: string;
constructor(private storage: StorageService) {
this.storage.output.subscribe(d => {
console.log(`child ${this.param} received ${JSON.stringify(d)}`);
this.data = d[this.param];
});
}
ngOnInit() {
}
}
答案 0 :(得分:0)
如果我理解正确,您可以将output
转换为接受您想要观察的“密钥”的方法。
output(key: string): Observable<any> {
return Observable.of(this.data[key])
.merge(this.output.map(newData => newData[key]))
.filter(Boolean) // Emit only when there's any data?
}
这种方式当您使用新数据调用this.output.next()
时(即使它仅包含已更改的键),它也会通过新数据通知所有观察者。
答案 1 :(得分:0)
如果您想获取服务数据,我会这样做:
storage.service.ts
import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs/Rx';
@Injectable()
export class StorageService {
externalEvent = Observable.interval(2500);
data = {};
private _outputEvent$: Subject<any> = new Subject<any>();
constructor() {
this.externalEvent.subscribe(n => {
this.data = {"a": Math.random(), "b": Math.random(), "c": Math.random()};
this.setOutputEvent(this.data);
});
}
/**
* Transform OutputEvent subject to an observable.
*/
getOutputEvent() {
return this._outputEvent$.asObservable();
}
/**
* Sends data through OutputEvent subject.
* @param value data to output.
*/
setOutputEvent(value: any) {
this._outputEvent$.next(value);
}
}
app.component.ts
import { Component } from '@angular/core';
import { StorageService } from './storage.service';
@Component({
selector: 'app-root',
template: `
<app-child [param]="'a'"></app-child>
<app-child [param]="'b'"></app-child>
`,
providers: [StorageService]
})
export class AppComponent { }
child.component.ts
import { Component, OnInit, Input } from '@angular/core';
import { StorageService } from './storage.service';
@Component({
selector: 'app-child',
template: `
<p>{{ data }}</p>
`
})
export class ChildComponent implements OnInit {
@Input() param: string;
data: string;
constructor(private storage: StorageService) {
this.storage.getOutputEvent().subscribe(
response => {
console.log(`child ${this.param} received ${JSON.stringify(response)}`);
// this.data = response[this.param];
this.data = response.param;
},
error => {
console.log(error);
}
);
}
ngOnInit() {
}
}