我有两个组件,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
});
}
}
请解释为什么它在父子组件之间起作用,而在两个无关的组件之间不起作用。还请帮助我如何在两个不相关的组件之间进行这项工作。预先感谢
答案 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 { }
答案 1 :(得分:0)
您必须提供根目录服务才能使其在全球范围内运行。
默认情况下,Angular CLI命令会为您执行此操作:
ng g service ButtonClick