Как вызвать компонентный метод из сервиса? (угловой2)

Я хочу создать сервис, который может взаимодействовать с одним компонентом. Все остальные компоненты в моем приложении должны иметь возможность вызывать эту службу, и эта служба должна взаимодействовать с этим компонентом.

Как вызвать компонентный метод из сервиса?

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

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

Из этого сервива?

@Injectable()

export class Service {


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

comment
Вы должны извлечь метод callComponentsMethod в службу, а затем внедрить службу в оба места.   -  person Jari Pekkala    schedule 24.11.2016


Ответы (3)


Взаимодействие между компонентами действительно может быть достигнуто с помощью сервисов. Вам нужно будет внедрить использование службы для межкомпонентной связи во все компоненты, которые должны будут ее использовать (все вызывающие компоненты и вызываемый метод), и использовать свойства Observables.

Общий сервис может выглядеть примерно так:

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

person Tudor Ciotlos    schedule 24.11.2016
comment
Он вызывает callComponentMethod, но не вызывает componentMethodCallSource. Ты хоть представляешь почему? - person Max K; 24.11.2016
comment
Я не совсем понимаю твой вопрос. Конечным результатом является то, что Component1 вызывает метод из Component2. Разве это не то, что вам нужно? - person Tudor Ciotlos; 24.11.2016
comment
Не понимаю почему, но нужную функцию не вызывает. - person Max K; 24.11.2016
comment
Вы имеете в виду в своем приложении, верно? Не могли бы вы заглянуть в консоль, чтобы увидеть, есть ли ошибки? - person Tudor Ciotlos; 24.11.2016
comment
Нет. Ошибок нет. Я вижу console.logs только в callComponentMethod, но он не вызывает необходимый метод. - person Max K; 24.11.2016
comment
Убедитесь, что вы зарегистрировали общую службу в качестве поставщика в корневом модуле. Если проблема не в этом, покажите, пожалуйста, код вашего приложения, чтобы я мог посмотреть. - person Tudor Ciotlos; 24.11.2016
comment
Давайте продолжим это обсуждение в чате. - person Max K; 24.11.2016
comment
Может ли он вызвать компонент из другого модуля? - person Max K; 24.11.2016
comment
Я тестировал только ситуацию, когда компоненты находятся в одном модуле, я не думаю, что это работает с разными модулями. - person Tudor Ciotlos; 24.11.2016
comment
@Tudor Ciotlos, Ваше вышеупомянутое решение действительно хорошее. Как передать значение из компонента 1 в компонент 2 в параметре метода? - person Anil Jagtap; 12.04.2017
comment
@AnilJagtap Взгляните на этот пример: angular.io/docs/ts/latest/cookbook/ - person Tudor Ciotlos; 13.04.2017
comment
@TudorCiotlos, не могли бы вы объяснить мне, как я могу вызвать компонентный метод из служебного метода? Не из другого компонента. Я использую одно и то же раскрывающееся меню в различных компонентах, поэтому мне нужно, чтобы каждый компонент реализовал свою собственную версию метода службы, который вызывается при выборе параметра. - person Rafael de Castro; 08.01.2018
comment
Я тестировал то, что объяснил Тудор Чотлос, и это работает, только если все компоненты находятся в одном модуле. Если вы хотите работать с этим решением и отдельными модулями, вам необходимо внести изменения. - person ; 28.11.2018
comment
чем чаще я вызываю эту функцию, она запускается дважды или чаще. Каждый раз, когда я звоню, в следующий раз это +1. Итак, если я использовал эту функцию 10 раз, в следующий раз она будет вызвана 11 раз. - person Sithys; 16.01.2021
comment
@Sithys, не видя вашего кода, лучше всего, что у вас проблема с утечкой памяти RxJs. Эта статья может помочь: netbasal.com/ - person Tudor Ciotlos; 17.01.2021

Вопрос не требует взаимодействия компонентов, он требует вызова метода компонента из службы.

Это просто может быть достигнуто путем внедрения сервиса в компонент. Затем определите метод внутри службы, который принимает функцию в качестве параметра. Метод должен сохранить эту функцию как свойство службы и вызывать ее где угодно.

// -------------------------------------------------------------------------------------
// 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
  }
}
person canbax    schedule 03.09.2019
comment
Спасибо, ты спас мне день - person Faouzi; 07.11.2019
comment
@canbax можно ли таким образом отправлять данные от службы к компоненту? - person Raphael; 04.06.2020
comment
@ Рафаэль, конечно. Вам просто нужно внедрить службу внутри конструктора компонента и использовать службу. - person canbax; 04.06.2020

поскольку этот пост немного устарел, я актуализирую ответ Тюдора на 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");
  }
person Eliseo    schedule 27.08.2019
comment
это работает нормально, но дело в том, что возникли множественные проблемы с вызовом - person SHUBHASIS MAHATA; 19.06.2020