主题不在两个不相关的组件之间工作
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 { }
我有两个组件,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 { }