【问题标题】:Call a compnent from a service从服务调用组件
【发布时间】:2019-04-17 01:36:11
【问题描述】:

我有 2 个组件需要通信,中间有一个服务。

服务

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

@Injectable()
export class CommunicationService {

  // Observable string sources
  private onOpen = new Subject<any>();

  // Observable string streams
  onOpen = this.onOpen.asObservable();

  // Service message commands
  callComponentMethod() {
    this.onOpen.next();
  }

}

组件 A

    import { Component } from '@angular/core';
import { CommunicationService } from './communication.service.ts'

@Component({
  selector: 'app-comp1',
  template: `
    <button type="button" (click)="callMethod()">Call method from Component1</button>
  `
})
export class Component1 {

  constructor( private communicationService: CommunicationService  ) { }

  callMethod = function () {
    this.communicationService.onOpen();
  }

}

组件 B

import { Component } from '@angular/core';
import { CommunicationService } from './communication.service.ts'

@Component({
  selector: 'app-comp2',
  template: ``
})
export class Component2 {

  constructor( private communicationService: CommunicationService  ) {

    this.communicationService.onOpen.subscribe(
        () => {
          alert('(Component2) onOpen');
        }
      );

  }

}

在这个 plunker 之后:http://plnkr.co/edit/SmntWy0GTNdvGB5Jb3hO?p=preview 调用了该方法,但是我想传递一个参数。我该怎么做呢 ?

【问题讨论】:

  • 也许你可以在流中传递参数:callComponentMethod(params) { this.onOpen.next(params); }
  • 你想传递哪个参数?
  • 取决于哪里,现在我希望有一个自定义类型的对象

标签: angular observable


【解决方案1】:

您的实现有很多不正确的地方。以下是您想要实现的工作示例:

Example

你不需要使用Subject,你可以使用普通的 observable,然后将新值“推送”到该 observable 的发射器:

export class CommunicationService {
  // Observable string sources
  private emitter: any;
  public messageInbox: Observable<any>

  constructor(){
     this.messageInbox = Observable.create(e => this.emitter = e);
  }

  // Service message commands
  public SendMessage() {
    this.emitter.next("hello");
  }

您的组件中的代码大部分都可以。

【讨论】:

  • 再次抱歉,我正在使用这种事件,但是,EventEmitter 不是更好吗?组件 A 和 C 不相关。另外,我不明白为什么我需要发射器和消息,这不能只用 1 个元素来完成吗?
  • @Bobby 从技术上讲是的,它可能是一个单独的 var,但我个人认为这是一个更好的实现,因为在这种情况下,我将 emitter 设为私有,messageInbox 设为公开。所以这个服务之外的任何东西都不能发出事件——所以关注点分离。我相信EventEmitter 也可以正常工作。
【解决方案2】:

调用callComponentMethod 类的callComponentMethod 函数而不是调用onOpen。其次,如果你想传递信息,你可以通过将值传递给callComponentMethod函数来实现。

下面是修改后的代码

通讯服务

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

@Injectable()
export class CommunicationService {

  // Observable string sources
  private onOpen = new Subject<any>();

  // Observable string streams
  onOpen = this.onOpen.asObservable();

  // Service message commands
  callComponentMethod(info:any) {
    this.onOpen.next(info);    //<-- pass the value to subscribers
  }

}

组件1

import { Component } from '@angular/core';
import { CommunicationService } from './communication.service.ts'

@Component({
  selector: 'app-comp1',
  template: `
    <button type="button" (click)="callMethod()">Call method from Component1</button>
  `
})
export class Component1 {

  constructor( private communicationService: CommunicationService  ) { }

  callMethod = function () {
    let obj = { name : "john" }; //<-- you can pass the value from callMethod
    this.communicationService.callComponentMethod(obj);   //<-- changed here
  }

}

【讨论】:

    猜你喜欢
    • 2019-08-22
    • 1970-01-01
    • 2023-03-20
    • 2011-09-18
    • 2018-05-05
    • 1970-01-01
    • 2017-04-10
    • 1970-01-01
    相关资源
    最近更新 更多