【问题标题】:Can we use same service to communicate between multiple pair of components in Angular using same service我们可以使用相同的服务在使用相同服务的 Angular 中的多对组件之间进行通信吗
【发布时间】:2019-11-12 14:49:55
【问题描述】:

假设我的页面有 4 个组件 Comp1、Comp2、Comp3 和 Comp4(所有不相关的组件)。如果我想在 Comp1 和 Comp2 之间进行通信。同时在 Comp3 和 Comp4 之间。是否可以使用相同的服务在它们之间进行通信?

【问题讨论】:

  • 我想回答是的。但是你能描述更多你做了什么以及你想做什么吗?

标签: angular angular-material angular-services


【解决方案1】:

简短的回答是根处的可注入服务可以用作组件之间的通信手段。使用 EmitEvent,您可以广播和订阅特定呼叫。

@Injectable({
    providedIn: 'root'
})
export class myInjectableService {
    public message: EmitEvent<string> = new EmitEvent();

    public SendMessage(msg:string): void {
         this.message.emit(msg);
    } 
}



@Component({
    selector: "sendComponent",
    template: "<div (click)='SendMessage()'></div>"
})
export class SenderComponent {
    constructor(private injectable: myInjectableService) {}
    public SendMessage(): void {
        this.injectable.SendMessage('Test');
    }
} 



@Component({
    selector: "receiveComponent",
    template: "<div>{{Message}}</div>"
})
export class ReceiverComponent {
    constructor(private injectable: myInjectableService) {
        this.injectable.subscribe((msg) => {
            this.Message = msg;
        })
    }
    public Message: string = null;
} 

【讨论】:

    【解决方案2】:

    是的,你可以做到。

    只需声明一个在主模块中提供的服务(如果您还没有触及默认值是appModule)。

    服务看起来像这样:

    import { Injectable } from "@angular/core";
    
    import { Subject } from 'rxjs';
    
    @Injectable()
    export class DataService { 
        private $data = new Subject<CommunicationData>();
        public dataReceivedEvent = this.$data.asObservable();
    
        public setDataToSend(data: CommunicationData): void {
            this.$data.next(data);
        }
    }
    

    CommunicationData 是一个接口:

    export interface CommunicationData { 
        eventName: string;
        data: any;
    }
    

    现在只需将此服务作为 DI 注入到您喜欢的每个组件中。

    constructor(
      private dataService: DataService
    ) { }
    

    要从这些组件发送数据,您可以这样做:

    private sendData(): void { 
      this.dataService.setDataToSend({
        eventName: 'YourCustomEvent',
        data: null //can be anything
      });
    }
    

    要捕获事件,只需执行以下操作(在组件的 onInit 生命周期中):

    this.dataService.dataReceivedEvent
      .subscribe(result => {
        if(result.eventName === 'YourCustomEvent') { 
          //foo
        } else if (result.eventName === '...') { 
          // something else
        } //and so on
      });
    

    通过这种方式,您将只有一个服务来保持所有组件之间的通信。

    【讨论】:

    • 谢谢@jacopo。这是一个有趣的解决方案。
    • 我目前正在将此解决方案用于一个包含大约 120 个组件和 300 万行代码的项目中,我会说它就像一个魅力。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-07
    • 1970-01-01
    相关资源
    最近更新 更多