我有一个组件(我们称之为CA),它创建了许多组件(CB)。 每个组件CB从服务类调用相同的函数。
此函数创建并返回一个Observable。 在这个Observable的回调函数中(让它称之为O1),它订阅了另一个Observable(O2),它是服务类的成员
只要从WebSocket连接接收数据,Obseable O2就会将数据推送给观察者。
在Observable O1中,当它从O2接收数据时,会将此数据推送给其观察者。
我的问题是,我的组件CB(正如我之前所说,订阅此Observable(O1)不会收到O1发送的数据。
当调试O1回调代码时,我可以在O1从O2接收数据时中断。然后,它执行" observer.next(dataReceivedFromO2)"。 但订阅者(每个组件C2中有1个)没有收到任何数据,我也不明白为什么。
任何人都可以帮我解决这个问题吗?提前感谢您的帮助
Node version: 8.4.0
Here are my dependencies:
"dependencies": {
"@angular/animations": "5.2.0",
"@angular/cdk": "5.0.4",
"@angular/common": "5.2.0",
"@angular/compiler": "5.2.0",
"@angular/core": "5.2.0",
"@angular/flex-layout": "2.0.0-beta.12",
"@angular/forms": "5.2.0",
"@angular/http": "5.2.0",
"@angular/material": "5.0.4",
"@angular/platform-browser": "5.2.0",
"@angular/platform-browser-dynamic": "5.2.0",
"@angular/router": "5.2.0",
"bootstrap": "4.0.0-beta",
"core-js": "2.5.3",
"font-awesome": "4.7.0",
"hammerjs": "2.0.8",
"material-design-icons": "3.0.1",
"rxjs": "5.5.6",
"typedoc": "0.9.0",
"zone.js": "0.8.20"
},
"devDependencies": {
"@angular/cli": "1.6.4",
"@angular/compiler-cli": "5.2.0",
"@angular/language-service": "5.2.0",
"@types/jasmine": "2.8.3",
"@types/jasminewd2": "2.0.3",
"@types/node": "9.3.0",
"codelyzer": "4.0.2",
"jasmine-core": "2.8.0",
"jasmine-spec-reporter": "4.2.1",
"karma": "2.0.0",
"karma-chrome-launcher": "2.2.0",
"karma-cli": "1.0.1",
"karma-coverage-istanbul-reporter": "1.3.3",
"karma-firefox-launcher": "1.1.0",
"karma-jasmine": "1.1.1",
"karma-jasmine-html-reporter": "0.2.2",
"karma-json-reporter": "1.2.1",
"protractor": "5.2.2",
"ts-node": "4.1.0",
"tslint": "5.9.1",
"typescript": "2.6.2"
}
这是我的服务:
注意:在这里,O2被命名为" liveObservable"。 FunctiongetLiveResumeData()将一个Observable(在我们的Context中也称为O1)返回给调用它的每个组件。
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { WebsocketService } from './websocket.service';
import { IResumeReadings } from './../types/resume.readings';
@Injectable()
export class ResumeLiveService {
resumeWebSocket: WebSocket;
started = false;
counter = 0;
liveObservable: Observable<IResumeReadings[]>;
constructor(private websocketService: WebsocketService) {
this.openService(this.websocketService);
if (!this.started) {
this.resumeWebSocket.onopen = () => {
this.resumeWebSocket.send('get_resume_data');
this.started = true;
};
}
// Here is my Observable O2
this.liveObservable = Observable.create((observer) => {
// When data comes from WebSocket, data are sent to observer
this.resumeWebSocket.onmessage = (message: any) => {
const bodyAsJson: IResumeReadings[] = JSON.parse(message.data);
// Sending data to observer
observer.next(bodyAsJson);
};
this.resumeWebSocket.onerror = (error) => {
observer.error(error);
};
return () => {
// If all components (C2) have unregistered from their respective Observable,
// the service sends over websocket a message to stop sending data
if (this.started && this.counter === 0) {
this.resumeWebSocket.send('stop_resume_data');
this.started = false;
}
};
});
}
// Function that is called by each Component (C2)
getLiveResumeData(id ?: number): Observable<IResumeReadings[]> {
if (!this.started) {
this.counter = 0;
if (this.resumeWebSocket.readyState === this.resumeWebSocket.OPEN) {
this.resumeWebSocket.send('get_resume_data');
this.started = true;
} else {
this.resumeWebSocket.onopen = () => {
this.resumeWebSocket.send('get_resume_data');
this.started = true;
};
}
}
this.counter += 1;
// We create and return an Observable (O1) which push data to observers when
// it receives data from liveObservable (O2)
return Observable.create((observerTest) => {
const subs = this.liveObservable.subscribe((data) => {
observerTest.next(data);
}, (error) => {
observerTest.error(error);
});
return () => {
subs.unsubscribe();
this.counter -= 1;
};
});
这是我的组件(C2)
export class MeasurementCardComponent implements OnInit, OnDestroy {
@Input()
measurementInfo: IMeasurementInfo;
@Input()
formID: string;
data: Observable<IResumeReadings[]>;
alarmStatus: AlarmStatus;
liveResumeSub: Subscription;
constructor(private utilsService: UtilsService,
private resumeLiveService: ResumeLiveService) { }
ngOnInit() {
// Storing Observable (O1) from service
this.data = this.resumeLiveService.getLiveResumeData(this.measurementInfo.id);
// We subscribe to this Observable
this.liveResumeSub = this.data.subscribe(
(readings) => {
// ==============> !!!!!!!!!!! NEVER COMES OR BREAKS HERE :-( !!!!!!!!!!!!!!!!!! <==================
if (readings[0].limits) {
for (const limit of readings[0].limits) {
this.formControls[limit.name] = this.formBuilder.control(limit.value, [Validators.required]);
}
}
const previousAlarmStatus = this.alarmStatus;
this.alarmStatus = this.utilsService.measurementStyleAlarm(readings[0]);
if (this.alarmStatus !== previousAlarmStatus) {
this.setCardAlarmStyle();
}
},
(err: HttpErrorResponse) => {
if (err.error instanceof Error) {
// A client-side or network error occurred.
console.log(`An error occured while getting resume readings for cards: ${err.error.message}`);
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong
console.log(`While getting resume readings for cards, Web server returned code ${err.status},` +
`message was: ${err.message}`);
}
},
() => {
console.log('complete');
});
}