【问题标题】:Angular : Call Function from different component with Service SharingAngular:使用服务共享从不同组件调用函数
【发布时间】:2018-09-06 14:24:07
【问题描述】:

我想实现这个-

// component1
load(){ 
  // code... 
}

// component2
component1.load();

所以,基本上我只想从一个组件中调用不同组件的函数。

我通过互联网阅读了组件之间共享数据的 3 种方法,在我的应用程序中,我使用服务共享在组件之间共享数据。

但是我怎样才能通过服务共享的方式简单地从不同的组件调用一个函数呢?

【问题讨论】:

  • 这些组件是否相互关联?他们之间有亲子关系吗?
  • @SiddharthAjmera 不,他们是兄弟姐妹

标签: angular service angular5 angular6


【解决方案1】:

您可以基于 observables 使用以下服务。它使用消息作为字符串,但如果您需要在组件之间传递数据,您可以使其更通用。在我的正常服务中,我通常会传递一个包含消息类型和消息数据的消息,例如

基本上,一个组件组件广播消息,另一个组件监听消息

试试这个

message-service.ts

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


@Injectable()
export class MessageService
{
  //subject to trigger events
  private mySubject: Subject<any> = new Subject<string>();
  //observable to listen to events
  public readonly messageReceived$: Observable<string> = this.mySubject.asObservable();

  //
  brodcast(message: string)
  {
    this.mySubject.next(message );
  }
}

component1.ts

constructor(private service: MessageService){}
//...
this.service.broadcast('triggerLoadMethod'); //broadcast a message for service subscriber to receive

组件2

constructor(private service: MessageService)
{
    //subscribe to observableto receive messages
    this.service.messageReceived$.subscribe( message =>
        {
        if(message == 'triggerLoadMethod') //if we are interested in the message, process it
        {
            this.load();
        }
    });
}

【讨论】:

  • 它有效,谢谢,但你能用 cmets 解释你的解决方案是什么流程,哪条线在做什么?这会更有帮助。
  • 我加了一些cmets
【解决方案2】:

您可以使用BehaviorSubject。方法如下。

应用组件模板:

App Component!

<hello></hello>
<sibling></sibling>

事件服务

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

@Injectable()
export class EventService {
  event: BehaviorSubject<any> = new BehaviorSubject<any>(null);

  emitEvent(data) {
    console.log('next Called with ', data);
    this.event.next(data);
  }
}

你好组件:

从'@angular/core'导入{组件,输入};

import { EventService } from './event.service';

@Component({
  selector: 'hello',
  template: `<h1>Hello {{name}}!</h1>`,
  styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent  {

  constructor(private eventService: EventService) {}

  ngOnInit() {
    this.eventService.event
      .subscribe(data => {
        console.log('data received', data);
        this.someMethod(data);
      });
  }


  someMethod(data) {
    console.log('some method got called!', data);
  }

}

兄弟组件:

import { Component, Input } from '@angular/core';

import { EventService } from './event.service';

@Component({
  selector: 'sibling',
  template: `<button (click)="onClick()">Call Hello Component's Method</button>`,
  styles: [`h1 { font-family: Lato; }`]
})
export class SiblingComponent  {

  constructor(private eventService: EventService) {}

  onClick() {
    console.log('onClick Called');
    this.eventService.emitEvent({ foo: 'bar' });
  }

}

这里有一个StackBlitz 供您参考。

【讨论】:

    【解决方案3】:

    我认为您通常不会直接调用该方法。保持关注点分离是件好事。最好的方法是使用 observables 来处理这个问题。

    服务:

    从 '@angular/core' 导入 { Injectable }; 从'rxjs'导入{主题};

    @Injectable({
      providedIn: 'root',
    })
    export class EventService {
    
      myEvent: Subject<void>;
    
      constructor() { 
         this.myEvent = new Subject<void>();
      }
    
      getEvent() {
          return this.myEvent.asObservable();
      }
    
      callEvent() {
          this.myEvent.emit();
      }
    
    
    }
    

    组件1:

    constructor(private eventService: EventService);
    ngOnInit() {
        this.eventService.subscribe(event => this.load())
    } 
    
    load() {
    
    }
    

    组件2

    constructor(private eventService: EventService);
    ngOnInit() {
        this.eventService.callEvent();
    } 
    

    这样,component2 可以随时发布事件。就此而言,任何组件都可以随时调用该事件。并且 Component1 可以订阅该事件。就此而言,任何组件都可以订阅该事件。所以代码更具可扩展性和可维护性。

    【讨论】:

    • 好吧,我喜欢关注点分离的方式,但是在你的解决方案中,如果我们有多个事件,你能解释一下吗?如果您有一个单一的事件服务并且我们的目标是维护单独的事件服务来处理事件共享,您将如何在这里识别不同的事件?
    • 用更具体的例子来回答这个问题会更容易。一般来说,我会尽量让每个服务都有一个单一的职责。所以我经常在我的站点中使用 NavbarEvent 服务,这样我就可以从不同的组件打开和关闭侧导航栏。您可能还需要 AuthService,以便登录页面和注册页面都可以发布登录事件。许多服务可能会订阅它。 AuthService 也可能有注销事件。你可以尝试做一些通用的东西来发布一个带有类型的事件,但如果可能的话我会避免这样做。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-15
    • 2019-03-05
    • 2017-11-06
    • 2021-05-03
    • 2019-05-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多