Angular 从应用程序组件到路由的通信

Angular Communicating from app component to a route

我正在处理一个带路由的 Angular 项目。我已经在从路由到应用程序组件进行通信并在那里更新它的值。但是,当我尝试将该信息发送到另一条路线(浏览器中可能未显示)时,我无法访问它。我只需要在该特定路线中使用此信息,并会使用任何可以完成此操作的方法。

在app.component.ts我有

import { Component, OnInit, OnDestroy } from '@angular/core';
import { RouterModule } from '@angular/router';
import { Subscription } from 'rxjs';
import { MessageService } from './message.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent implements OnInit, OnDestroy{
public message = "Discover Workouts";
public state:boolean = false; 

subscription: Subscription;
  
  //Inject MessageService
  constructor(private messageService: MessageService) {
    this.subscription = this.messageService.getMessage()
      .subscribe(mymessage => this.message = mymessage)
  }
ngOnInit(){
}
  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

在锻炼中-options.ts我有这个

import { Component, Output, EventEmitter,  OnDestroy, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { MessageService } from '../message.service';
import { Sio2service } from '../sio2.service';

@Component({
  selector: 'app-workout-options',
  templateUrl: 'workout-options.component.html',
  styleUrls: ['../app.component.css']
})
export class WorkoutOptionsComponent implements OnDestroy{
mymessage: string;
subscription: Subscription;

@Output() public childEvent = new EventEmitter();
  constructor(private messageService: MessageService) {
this.subscription = this.messageService.getMessage()
.subscribe(mymessage => { this.mymessage = mymessage; });
}

OnInit(){
 }
 
FupdateParent(exerName:string) {
    this.messageService.updateMessage(exerName);
//  this.sio2.sendMsg(exerName);
//console.log(exerName);
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

在message.service中,我有

import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';
 
@Injectable({ providedIn: 'root' })
export class MessageService {
    private myMessage = new Subject<string>();
 
    updateMessage(message: string) {
        this.myMessage.next(message);
    }
 
    clearMessage() {
        this.myMessage.next();
    }
 
    getMessage(): Observable<string> {
        return this.myMessage.asObservable();
    }
}

到目前为止一切正常。但是,当我尝试在 start-workout.ts(作为路由实现)中接收后一个组件(也作为路由实现)发送的值时,我不能。

这是我试过的。

在开头-workout.component.ts我有这个(部分代码)

export class StartWorkoutComponent implements OnInit{
public message = "";
subscription: Subscription;

  constructor(private messageService: MessageService, private httpClient: HttpClient){
this.subscription = this.messageService.getMessage()
.subscribe(mymessage => { this.message = mymessage; });
}

ngOnDestroy() {
  this.subscription.unsubscribe();
}

我一定是做错了什么。有人可以指导我吗

我认为问题出在您对 Subject 的使用上。您的 StarWorkOutComponent 直到消息发出其事件后才会初始化。

如果您使用 BehaviorSubject,迟到的订阅者将获得当前值,因此如果设置了消息,那么您加载该页面时它将以您的其他组件已经设置的当前值开始。

请注意,当您创建一个新的 BehaviorSubject 时,您需要为其赋值,因此在您的服务中进行以下更改:

// old
private myMessage = new Subject<string>();

// new, initialize with empty string, or you could use null as well in case your subscribers want to filter out cases of null and show their own default values
private myMessage = new BehaviorSubject<string>("");

有关 BehaviorSubject 的更多详细信息,请参见此处:https://rxjs-dev.firebaseapp.com/guide/subject#behaviorsubject

问题就在这里

private myMessage = new Subject<string>();

Subject 仅触发那些在触发事件时订阅的订阅。为了在其他路由中获取数据,您必须将消息更改为 ReplaySubject,无论订阅何时发生,它都会为每个人提供值。

查看 RXJS 文档以获取有关 Subjects and ReplaySubjects

的更多信息

解决方案:更改消息服务

export class MessageService {
private myMessage = new ReplaySubject<string>();

updateMessage(message: string) {
    this.myMessage.next(message);
}

clearMessage() {
    this.myMessage.next();
}

getMessage(): Observable<string> {
    return this.myMessage.asObservable();
}

}