Angular - 订阅另一个组件设置的共享服务变量时,未定义非子接收组件数据

Angular - Non child receiving component data is undefined when subscribed to a shared service variable which another component sets

我一直在尝试在两个不相关的组件之间共享数据,并且为此使用了共享服务方法。我已经查看了数十个教程并尝试了使用服务的多种变体,但无论我做什么,每当我尝试 console.log() 接收组件中接收到的数据时,控制台日志什么都不显示。

服务:

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

@Injectable({
  providedIn: 'root'
})
export class StatusBoxService 
{   
  private messageSource = new Subject<any>();
  currentMessage = this.messageSource.asObservable();

  constructor() {}
  
  changeMessage(message: any)
  {
    this.messageSource.next(message);
  }

}

供应组件:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subject, Subscription } from 'rxjs';
import { StatusBoxService } from '../../services/status-box.service';

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

export class LiveSummaryComponent implements OnInit 
{

constructor(private data: StatusBoxService) { }

  ngOnInit(): void 
  {
     this.data.changeMessage('hello world')   
  }

  ngOnDestroy(): void
  {
    //this.subscription.unsubscribe();
  }
}

接收组件

import { Component, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { Subscription } from 'rxjs';
import { StatusBoxService } from 'src/app/services/status-box.service';
import { ConfirmActionComponent } from '../confirm-action/confirm-action.component';

@Component({
  selector: 'app-delete-status-box',
  templateUrl: './delete-status-box.component.html',
  styleUrls: ['./delete-status-box.component.css']
})
export class DeleteStatusBoxComponent implements OnInit {

  subscription!: Subscription;
  selectedDevice = '';
  testy!: any;

  constructor(private form: FormBuilder, public dialog: MatDialog, private dialogRef: MatDialogRef<DeleteStatusBoxComponent>, private data: StatusBoxService) 
  {
    //this.data.currentMessage.subscribe(param => this.testy = param) // doesn't work
    this.subscription = this.data.currentMessage.subscribe((data: any) => 
      {
        this.testy = data;
      }); // doesn't work
  }

  DeleteStatusBoxForm = this.form.group({
    selectedDevice: ['']
  });

  ngOnInit() 
  {
    console.log(this.testy);
  }

  deleteStatusBox()
  {
    this.dialog.open(ConfirmActionComponent)
    //this.dialogRef.close();
  }
}

在接收组件中,当我订阅服务中的 currentMessage 变量时,我打印出分配给传入数据的 testy 变量。

不知何故,当我 console.log() 它显示未定义的易怒变量时,我不知道为什么:

组件如何交互:

app-live-summary 组件是一个页面,它是 <router-outlet></router-outlet> 与其他页面的一部分。 app-live-summary 包含多个其他组件。

app-live-summary 页面中包含的组件之一是 app-header。此 app-header 组件包含一个按钮,单击该按钮会以模式弹出框的形式打开 app-delete-status-box 组件。

app-live-summary 组件也有一些我想传递给 app-delete-status-box 当按钮被点击时。

如果您的组件按此顺序使用:

<app-delete-status-box></app-delete-status-box>
<app-live-summary></app-live-summary>

您不会获得任何数据,因为您在 app-delete-status-box 组件实例化后发送一个值并尝试在 ngOnInit 方法上控制它,该方法只会在您的组件在视图中初始化时触发。尝试更改顺序并控制订阅内的值更改:

ngOnit(){
 this.subscription = this.data.currentMessage.subscribe((data: any) => 
      {
        this.testy = data;
        console.log(this.testy)
      });
}

如果 app-delete-status-box 是对话框组件,您可以使用 dialog.open(yourComponent, data) 方法发送该值(调用那里的服务方法来获取值)。有关对话框的更多信息,请参见:https://material.angular.io/components/dialog/overview

我认为该组件的加载顺序不正确。 如果您将“console.log”移动到

this.subscription = this.data.currentMessage.subscribe((data: any) => 
  {
    this.testy = data;
    console.log(this.testy);
  });

有效吗?

在视图中,您可以使用 AsyncPipe 来获取可观察的结果。

{{ testy$ | async }}