Angular 5: как транслировать событие из authguard в заголовок?

Я пытаюсь транслировать событие из компонента 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, получатель в моем компоненте заголовка никогда не получает сообщение. Я могу подтвердить, что метод canActivate в authGuard вызывается для каждого пути.

Но когда я транслирую из компонента страницы (например, приборной панели), получатель в компоненте заголовка действительно получает сообщение.

Кто-нибудь знает, как опубликовать сообщение от authguard в моем компоненте заголовка?

Пожалуйста, используйте BehaviorSubject вместо Subject. Может быть, компонент заголовка вообще не активен, когда вы генерируете событие и нет подписки для вашего объекта.

Pratap A.K 19.09.2018 06:40
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
1
1
561
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Пожалуйста, используйте BehaviorSubject вместо Subject

BehaviorSubject содержит одно значение. Когда он подписан, он сразу же выдает значение. Тема не имеет ценности.

Пожалуйста, проверьте это https://stackoverflow.com/a/43351340/2742156

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

Подписчик всегда получает последнее переданное значение

Обновлено:

Сторожить

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(private broadcastService: BroadcastService) {}

  canActivate(): boolean {
    console.info('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.info('Inside login', res);
      });
}

конфигурация маршрута

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

Спасибо, BehaviorSubject кажется лучшей практикой. Но это все еще не решает проблему с передачей AuthGuard, не полученной в заголовке.

FruitDealer 19.09.2018 06:55

@FruitDealer вы не возвращаете логическое значение из метода canActivate. Пожалуйста, верните истину или ложь

Pratap A.K 19.09.2018 07:07

извините, я оставил код, чтобы он был понятнее для демонстрационных целей. Я отредактировал сообщение, чтобы включить возвращаемый тип.

FruitDealer 19.09.2018 07:11

@FruitDealer у меня работает с BehaviorSubject. Я дополню свой ответ тем, что пробовал. Если это все еще не сработало, создайте stackblitz, JsFiddle я исправлю для вас

Pratap A.K 19.09.2018 07:13
Ответ принят как подходящий

Вы должны использовать 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

отличается ли этот ответ от того, что я упомянул, за исключением Stackblitz?

Pratap A.K 19.09.2018 07:25

@FruitDealer попросил вас предоставить stackblitz, и я поставил эту демонстрацию перед вашим ответом, но я опоздал, чтобы опубликовать здесь .... и главное, что когда вы даете ответ другим с демонстрацией, это будет иметь значение ..

Aniket Avhad 19.09.2018 07:28

так что это зависит от @FruitDealer, ответ которого полезен для него.

Aniket Avhad 19.09.2018 07:28

@AniketAvhad Header - это компонент в моем app.component.html. Также на панели инструментов есть путь с авторизацией на нем. Я обновлю свой вопрос кодом

FruitDealer 19.09.2018 07:32

@FruitDealer сказал, что BehaviorSubject не работает для него, хотя он работает для меня и вас. Поэтому попросил его предоставить скрипку для определения проблемы.

Pratap A.K 19.09.2018 07:33

Насколько я понимаю, вы хотите, чтобы при нажатии на dashboard link вы хотели, чтобы сообщение было в header.component.

Aniket Avhad 19.09.2018 07:39

@AniketAvhad Да, правильно. Когда дашборд загружается, он вызывает authguard, который отправляет сообщение компоненту заголовка.

FruitDealer 19.09.2018 07:42

@AniketAvhad Кажется, ваше решение работает. Мой похож, и он не работает. Будет ли проблема с использованием Angular 5?

FruitDealer 19.09.2018 08:08

Другие вопросы по теме