当我订阅一个可观察的主题时,我无法获取数据(rxJS 5.5.2) [英] I can't get data when I subscribe to a subject as observable (rxJS 5.5.2)
问题描述
我发现此出色的代码可在我的组件中显示警报,但是,由于Angular 5.2.0和rxJS 5.5.2,我听不到警报。
I found this great code to display alert in my component but, since Angular 5.2.0 and rxJS 5.5.2, I can't get my alerts.
我将控制台日志显示在哪里,以了解问题所在,但我没有找到它。
I put some console log eveywhere to understand what is the problem but I didn't find it.
我认为问题在于主题可观察:我可以订阅它,但是没有数据。
I think the problem is about the subject asObservable : I can subscribe to it but there is no data.
alert.service.ts
alert.service.ts
import { Injectable } from '@angular/core';
import { Router, NavigationStart } from '@angular/router';
import { Observable } from 'rxjs';
import { Subject } from 'rxjs/Subject';
import { Alert, AlertType } from '../models/alert';
@Injectable()
export class AlertService {
private subject = new Subject<Alert>();
private keepAfterRouteChange = false;
constructor(private router: Router) {
// clear alert messages on route change unless 'keepAfterRouteChange' flag is true
router.events.subscribe(event => {
if (event instanceof NavigationStart) {
if (this.keepAfterRouteChange) {
// only keep for a single route change
this.keepAfterRouteChange = false;
} else {
// clear alert messages
this.clear();
}
}
});
}
getAlert(): Observable<any> {
return this.subject.asObservable();
}
success(message: string, keepAfterRouteChange = false) {
this.alert(AlertType.Success, message, keepAfterRouteChange);
}
error(message: string, keepAfterRouteChange = false) {
this.alert(AlertType.Error, message, keepAfterRouteChange);
}
info(message: string, keepAfterRouteChange = false) {
this.alert(AlertType.Info, message, keepAfterRouteChange);
}
warn(message: string, keepAfterRouteChange = false) {
this.alert(AlertType.Warning, message, keepAfterRouteChange);
}
alert(type: AlertType, message: string, keepAfterRouteChange = false) {
// I got my alert here from my component
this.keepAfterRouteChange = keepAfterRouteChange;
this.subject.next(<Alert>{ type: type, message: message });
}
clear() {
// clear alerts
this.subject.next();
}
}
alert.component.ts
alert.component.ts
import { Component, OnInit } from '@angular/core';
import { Alert, AlertType } from '../models/alert';
import { AlertService } from '../services/alert.service';
@Component({
selector: 'alert',
templateUrl: '../resources/views/alert.component.html',
styleUrls: ['../resources/scss/alert.scss'],
})
export class AlertComponent {
alerts: Alert[] = [];
constructor(private alertService: AlertService) { }
ngOnInit() {
// nothing appens here... no data in my console log
this.alertService.getAlert().subscribe(data => {
console.log("data");
console.log(data);
})
this.alertService.getAlert().subscribe((alert: Alert) => {
if (!alert) {
// clear alerts when an empty alert is received
this.alerts = [];
return;
}
// add alert to array
this.alerts.push(alert);
});
}
removeAlert(alert: Alert) {
this.alerts = this.alerts.filter(x => x !== alert);
}
cssClass(alert: Alert) {
if (!alert) {
return;
}
// return css class based on alert type
switch (alert.type) {
case AlertType.Success:
return 'alert alert-success';
case AlertType.Error:
return 'alert alert-danger';
case AlertType.Info:
return 'alert alert-info';
case AlertType.Warning:
return 'alert alert-warning';
}
}
}
component.ts /组件。 html(这里没什么特别的)
component.ts / component.html (nothing special here)
// in my component.ts
ngOnInit() {
this.alertService.warn("test");
....
}
in my component.html
<alert></alert>
编辑:由于@JD的解释,我通过用BehaviorSubject替换了主题来解决了这个问题
EDIT : thanks to @J.D explanation, I solved the problem by replacing the subject by a BehaviorSubject
推荐答案
我看到你 this.alertService.warn( test);
(这会在subject.ts中调用 next()
在Subject上),后者通常是顶级组件。然后,您订阅alert.component.ts,它在组件树中较低。这意味着您稍后订阅-这就是为什么没有数据的原因。因此,您可以使用其他Subject类型,例如BehaviorSubject:
I see you this.alertService.warn("test");
(this invokes next()
on Subject) in component.ts which is usually a top-level component. And you subscribe in alert.component.ts which is lower in component tree. That means you subscribe later - thats why no data comes. So you either use other Subject type, like BehaviorSubject:
private subject = new BehaviorSubject<Alert>(yourDefaultAlert);
或者在将值推送到Subject中之前进行订阅。您的服务类是单例,因此所有组件都共享它的同一实例-因此,如果您之前订阅,它将接收数据。
Or subscribe before you push values into Subject. Your service class is a singleton, so all components share the same instance of it - so if you subscribe before, it will receive data.
这篇关于当我订阅一个可观察的主题时,我无法获取数据(rxJS 5.5.2)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!