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();
}
}
我正在处理一个带路由的 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();
}
}