一定是很基本的东西,但我被困住了。
简而言之,我有三个服务: service0、service1、service3。Service1存储的数据和服务2&3与它一起工作。
我想订阅来自这两个服务的service1数据属性的更改。我该怎么做?
示例:
export class Service0 implements OnDestroy {
constructor(private service1: Service1) { }
add(data): boolean { this.service1.addData(data); }
}
export class Service1 implements OnDestroy {
data: Data;
constructor() { }
get data() { return this.data }
addData(data) {
if (this.servers.findIndex(el => el.hostname === s.hostname) === -1){
this.data.push(s);
}
}
}
export class Service2 implements OnDestroy {
data: Data;
constructor(private service1: Service1) { this.data = this.service1.data; }
}更新:--我尝试过这样做,它应该可以工作(数据服务):
import {Observable, of} from 'rxjs';
export class Service1 {
data: Data[];
constructor() { }
get data() { return this.data }
addData(data) {
if (this.servers.findIndex(el => el.hostname === s.hostname) === -1){
this.data.push(s);
}
}
getData(): Observable<Data[]> {
return of(this.data)
}
}
export class Service2 implements OnDestroy {
data: Data[];
constructor(private service1: Service1) {
this.service1.getData().subscribe(data=>{
this.data = data
console.log(this.data)
})
}
}一旦添加了对象,它就会触发,但在本例中,console.log(this.data)只在浏览器控制台中显示对象数组,而JSON.stringify(this.data)则试图调用属性--显示对象是空的。仍然喜欢这个解决方案,但不知道为什么会发生这种情况?
同时,现在我使用dataChanges = new Subject();在Service1中更改数据后发出一个事件,然后
this.servers1.serversChanges.subscribe(() => {
this.data = this.service1.getData();
});去拿它。在这种情况下,它起作用了。
发布于 2018-06-21 14:57:46
为了订阅某件东西,这件事必须是可观察的。为此,我们使用诸如Rxjs这样的库。有许多可观察到的rxjs,例如我们的主题、BehaviorSubjects、AsyncSubjects等。您可以在这里更多地阅读rxjs。
下面的示例展示了如何实现一个简单的可观察数据服务!
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
Injectable()
export class Service0 {
data: BehaviorSubject<string[]>;
constructor() {
this.data = new BehaviorSubject<string[]>([]);
}
getData() {
// Logic to get data from an http call
// On Successful response
this.data.next(responseData);
}
}现在,您可以在任何其他服务、组件等上注入该服务,并轻松地订阅数据。
import { Injectable } from '@angular/core';
import { Service0 } from '../service0.ts';
Injectable()
export class Service1 {
data: string[];
constructor(private service0: Service0) {
service0.data.subscribe(data => {
this.data = data;
});
}
dataFunction() {
// do stuff with data
}
}现在,您的第二服务将始终拥有将从Service0提供的最新数据。
我还想指出,如果您在组件中使用该功能,那么在不存在任何数据泄漏的情况下,真正做到这一点的最佳实践是取消订阅可观察到的内容。就像这样:
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
import { Service0 } from '../service0.ts';
@Component({
selector: 'my-component',
templateUrl: './my-component.component.html',
styleUrls: ['./my-component.component.scss']
})
export class MyComponent implements OnInit, OnDestroy {
data: string[];
dataSubscription: Subscription;
constructor(private service0: Service0) { }
ngOnInit() {
this.dataSubscription = this.service0.data.subscribe(data => {
this.data = data;
});
}
ngOnDestroy() {
this.dataSubscription && this.dataSubscription.unsubscribe();
}
}您不需要在Singleton服务中这样做,因为您在构造函数中订阅,并且该订阅只在该服务的生存期内持续。该构造函数将只被调用一次。如果该服务不是单个实例,那么您必须实现相同的逻辑,因为您可能需要创建该服务的多个实例。在这里读到关于单身汉的Angular.io。我希望我能给你一个答案来帮助你完成你的工作。如有任何问题,请随时与我联系。
干杯
发布于 2018-06-21 14:35:58
好的,我在注释中给出了一些想法,但是下面是代码:
export class Service0 implements OnDestroy {
constructor(private service1: Service1) {
// In case when you only inform without passing data
this.service1.dataChanges.subscribe(() => {
// This service doesn't have 'data' member so do something else
});
// With passed data
this.service1.dataChanges.subscribe((data) => {
// This service doesn't have 'data' member so do something else
});
}
add(data): boolean {
this.service1.addData(data); // Could be changed now to use that setter
}
}
export class Service1 implements OnDestroy {
_data: Data;
dataChanges = new Subject();
constructor() {
}
get data() {
return this._data;
}
set data(value) {
this._data = value;
this.dataChanges.next(); // or even pass here new value
}
}
export class Service2 implements OnDestroy {
data: Data;
constructor(private service1: Service1) {
this.data = this.service1.data;
// In case when you only inform without passing data
this.service1.dataChanges.subscribe(() => {
this.data = this.service1.data;
});
// With passed data
this.service1.dataChanges.subscribe((data) => {
this.data = data;
});
}
}https://stackoverflow.com/questions/50970878
复制相似问题