角度5:如何将事件从authguard广播到标头?

时间:2018-09-19 04:35:37

标签: angular

我正在尝试将事件从authguard组件广播到我的标头组件。

广播服务

@Injectable()
 export class BroadcastService {

 public subject = new Subject<any>();

 sendMessage(message: string) {
  this.subject.next(message);
 }
}

接收器(标头组件)

export class HeaderComponent {
  constructor(public broadcast: BroadcastService) {
    this.broadcast.subject.subscribe(message => {
    alert('broadcast received: ' + message);
   });
 }
}

广播(authguard组件-不起作用)

export class AuthGuard implements CanActivate {
 constructor(public broadcast: BroadcastService) {      
 }

 canActivate(): boolean {
  this.broadcast.sendMessage('Hi from AuthGuard');
  return true;
 }
}

广播(仪表板组件-工作原理)

export class DashbardComponent {
 constructor(public broadcast: BroadcastService) {      
 }

 ngOnInit() {
  this.broadcast.sendMessage('Hi from AppComponent');
 }
}

app.component.html

<headerComponent></headerComponent>
<router-outlet></router-outlet>

路由

{
 path: 'dashboard',
 component: DashboardComponent,
 canActivate: [AuthGuard]
}

问题在于,当我从authguard组件进行广播时,标头组件中的接收者永远不会收到消息。我可以确认对每个路径都调用了authGuard中的canActivate方法。

但是当我从页面组件(例如仪表板)广播时,标头组件中的接收者确实会收到消息。

有人知道如何将消息从authguard发布到我的标头组件吗?

2 个答案:

答案 0 :(得分:1)

您必须使用 BehaviorSubject

这是一个例子

boradcast.service.ts

import { Injectable } from '@angular/core';
import { Subject, BehaviorSubject } from 'rxjs'

@Injectable({
  providedIn: 'root'
})
export class BroadcastService {

  constructor() { }

  public subject = new BehaviorSubject<any>('');

  sendMessage(message: string) {
    this.subject.next(message);

  }

}

这是Stackblitz 演示

答案 1 :(得分:0)

请使用BehaviorSubject而不是Subject

BehaviorSubject拥有一个值。订阅后,它将立即发出该值。主题没有值。

请检查此 https://stackoverflow.com/a/43351340/2742156

let bSubject = new BehaviorSubject(null); // null or any default value
bSubject.subscribe(value => {
  console.log("Subscription got", value);
});

订户总是收到最后发出的值

已更新:

后卫

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(private broadcastService: BroadcastService) {}

  canActivate(): boolean {
    console.log('auth guard called');
    this.broadcastService.subject.next('from guard');
    return true;
  }
}

广播服务

@Injectable()
 export class BroadcastService {

 public subject = new BehaviorSubject<any>('hello');

 sendMessage(message: string) {
  this.subject.next(message);
 }
}

订户(标题组件)

constructor(private broadcastService: BroadcastService) {
broadcastService.subject.subscribe((res) => {
        console.log('Inside login', res);
      });
}

路由配置

{
    path: 'some route',
    component: SomeComponent,
    canActivate: [AuthGuard]
  }