主题不在两个不相关的组件之间工作

Subject not working between two unrelated components

我有两个组件,sourceComponent 和 targetComponent。我想在 sourceComponent 中的按钮单击事件上执行 targetComponent 中的函数。我决定为此使用 Subject。

sourceComponent.ts

export class SourceComponent{
    constructor(private btnclk: ButtonClickService){}
       onButtonClick(){
           this.btnclk.updateButtonClick(event);
       }
}

targetComponent.ts

export class TargetComponent{
    constructor(private btnclk: ButtonClickService){
        this.btnclk.getButtonClick().subscribe(event=>{
            console.log('Click from source component to target component') // not working
        });
    }
}

ButtonClickService.ts

@Injectable()
export class ButtonCLickService{
    private btnclk = new Subject<Event>();

    getButtonClick() : Observable<Event>{
        return this.btnclk.asObservable();
    }

    updateButtonClick(event : Event){
        this.btnclk.next(event);
    }
}

但是当我在 appComponent.ts 中订阅相同的点击事件时,它工作正常。

appComponenet.ts

export class AppComponent{
    constructor(private btnclk: ButtonClickService){
        this.btnclk.getButtonClick().subscribe(event=>{
          console.log('Click from source component to app component') //working
        });
    }
}

请解释为什么它在父子组件之间工作,而不在两个不相关的组件之间工作。另外请帮助我如何在两个不相关的组件之间进行这项工作。提前致谢

您必须在 root 中提供您的服务才能使其在全球范围内运行。

Angular CLI 命令默认为您完成:

ng g service ButtonClick

对于全局服务,您应该在根级别(通常是根 NgModule 或使用 providedIn: 'root')提供一次以在服务的同一实例(单例服务)上工作。来自 Angular 文档 (https://angular.io/guide/singleton-services)

我为您准备了示例演示,它会按您的预期运行:

ButtonClickService

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

interface Event {
  type: string;
  data: any;
}

@Injectable({
  providedIn: 'root' // <= using `providedIn: 'root'` to provide at root level
})
export class ButtonClickService {

  private btnclk = new Subject<Event>();

  getButtonClick(): Observable<Event> {
    return this.btnclk.asObservable();
  }

  updateButtonClick(event: Event) {
    this.btnclk.next(event);
  }

}

AppModule

@NgModule({
  imports:      [ BrowserModule, FormsModule ],
  declarations: [ AppComponent, HelloComponent, SourceComponent, TargetComponent ],
  bootstrap:    [ AppComponent ],
  providers: [] // <= don't need to provide on any NgModule
})
export class AppModule { }

在线演示:https://stackblitz.com/edit/angular-kxj1ax