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

时间:2019-09-04 03:50:29

标签: angular subject

我有两个组件,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中订阅相同的click事件时,它运行正常。

appComponenet.ts

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

请解释为什么它在父子组件之间起作用,而在两个无关的组件之间不起作用。还请帮助我如何在两个不相关的组件之间进行这项工作。预先感谢

2 个答案:

答案 0 :(得分:5)

对于全局服务,您应该在根级别(通常是根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

答案 1 :(得分:0)

您必须提供根目录服务才能使其在全球范围内运行。

默认情况下,Angular CLI命令会为您执行此操作:

ng g service ButtonClick