我发现this great code在我的组件中显示警告但是,自Angular 5.2.0和rxJS 5.5.2以来,我无法收到警报。
我把一些控制台日志放在哪里,以了解问题是什么,但我没有找到它。
我认为问题是关于主题asObservable:我可以订阅它但没有数据。
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
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 / component.html(这里没什么特别的)
// in my component.ts
ngOnInit() {
this.alertService.warn("test");
....
}
in my component.html
<alert></alert>
编辑:感谢@ J.D解释,我通过用BehaviorSubject替换主题来解决问题
答案 0 :(得分:1)
我在component.ts中看到你this.alertService.warn("test");
(这会在Subject上调用next()
,它通常是顶级组件。并且您在alert.component.ts中订阅,它在组件树中较低。这意味着您稍后订阅 - 这就是没有数据的原因。因此,您要么使用其他主题类型,例如BehaviorSubject:
private subject = new BehaviorSubject<Alert>(yourDefaultAlert);
或者在将值推送到Subject之前订阅。您的服务类是单例,因此所有组件共享相同的实例 - 因此,如果您之前订阅,它将接收数据。