如何从服务中调用组件方法?(Angular2)

31

我想创建一个服务,它可以与一个组件交互。 我的应用程序中的所有其他组件都应该能够调用此服务,而此服务应该与这个组件进行交互。

如何从服务中调用组件方法?

@Component({
  selector:'component'
})
export class Component{

  function2(){ 
    // How call it?
  }
}

来自这项服务?

@Injectable()

export class Service {


  callComponentsMethod() {
    //From this place?;
      }
}

你应该将 callComponentsMethod 方法提取到一个服务中,然后将该服务注入到两个位置。 - Jari Pekkala
3个回答

35
组件之间的交互确实可以使用服务来实现。您需要将用于组件间通信的服务注入到所有需要使用它的组件中(调用者组件和被调用方法),并利用可观察对象的属性。
共享服务可能如下所示:
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';

@Injectable()
export class CommunicationService {

  // Observable string sources
  private componentMethodCallSource = new Subject<any>();
  
  // Observable string streams
  componentMethodCalled$ = this.componentMethodCallSource.asObservable();

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

例子:

发件人:

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

接收者:

this.communicationService.componentMethodCalled$.subscribe(() => {
      alert('(Component2) Method called!');
});

我创建了一个基本示例在这里,在 Component1 中点击按钮将调用 Component2 的一个方法。

如果您想要阅读更多关于此主题的内容,请参考专门的文档部分:https://angular.io/guide/component-interaction#parent-and-children-communicate-via-a-service


@Tudor Ciotlos,您上面的解决方案真的很好。如何通过方法参数从组件1传递值到组件2? - Anil Jagtap
@TudorCiotlos,你能给我解释一下如何从服务方法中调用组件“方法”吗?不是从另一个组件中调用。我在各种组件中使用同一个下拉列表,所以我需要每个组件都实现自己版本的服务方法,当选择一个选项时它就会被调用。 - Rafael de Castro
我测试了Tudor Ciotlos所解释的内容,只有当所有组件在同一个模块中时才有效。如果您想使用这个解决方案并且分开成模块,您需要进行适应。 - user8193897
每次我调用这个函数,它就会被触发两次或更多。每次调用它,下一次就会加1。所以如果我使用这个函数10次,下一次它就会被调用11次。 - Sithys
@Sithys,没有看到你的代码,我最好的猜测是你有一个 RxJs 内存泄漏问题。这篇文章可能会有所帮助:https://netbasal.com/why-its-important-to-unsubscribe-from-rxjs-subscription-a7a6455d6a02 - Tudor Ciotlos
显示剩余10条评论

20

这个问题并不涉及组件间互动,而是询问如何从服务中调用组件方法。

只需将服务注入到组件中即可轻松实现。然后在服务内定义一个接受函数作为参数的方法。该方法应该将此函数保存为服务的属性,并在需要时调用它。

// -------------------------------------------------------------------------------------
// codes for component
import { JustAService} from '../justAService.service';
@Component({
  selector: 'app-cute-little',
  templateUrl: './cute-little.component.html',
  styleUrls: ['./cute-little.component.css']
})
export class CuteLittleComponent implements OnInit {
  s: JustAService;
  a: number = 10;
  constructor(theService: JustAService) {
    this.s = theService;
  }

  ngOnInit() {
    this.s.onSomethingHappended(this.doThis.bind(this));
  }

  doThis() {
    this.a++;
    console.log('yuppiiiii, ', this.a);
  }
}
// -------------------------------------------------------------------------------------
// codes for service
@Injectable({
  providedIn: 'root'
})
export class JustAService { 
  private myFunc: () => void;
  onSomethingHappended(fn: () => void) {
    this.myFunc = fn;
    // from now on, call myFunc wherever you want inside this service
  }
}

谢谢你,你救了我的一天。 - Faouzi
@canbax 这种方式可以从服务向组件发送数据吗? - Raphael
2
@Raphael 当然可以。你只需要在组件的构造函数中注入服务并使用该服务即可。 - canbax
1
天才而又简单,谢谢。 - danday74

4
由于这篇文章有些旧,我更新了Tudor的回复:stackblitz 这是关于服务的内容。
private customSubject = new Subject<any>();
  customObservable = this.customSubject.asObservable();

  // Service message commands
  callComponentMethod(value:any) {
    this.customSubject.next(value);
  }

主组件
constructor(private communicationService:CommunicationService){}
  ngOnInit()
  {
    this.communicationService.customObservable.subscribe((res) => {
          this.myFunction(res)
        }
      );
  }
  myFunction(res:any)
  {
    alert(res)
  }

另一个组件调用服务方法

constructor( private communicationService: CommunicationService  ) { }

  click() {
    this.communicationService.callComponentMethod("hello word");
  }

那个程序运行良好,但问题在于出现了多次调用的情况。 - SHUBHASIS MAHATA

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接