【问题标题】:Angular2 call method of other component其他组件的Angular2调用方法
【发布时间】:2016-11-03 11:12:23
【问题描述】:

我有一个 Angular2 应用程序,我在其中创建了一个 Header 组件,该组件在我的主 App 组件中呈现。

现在,我有另一个表单组件,它的提交按钮应该放在页眉中。我怎么能这样做?

我有点需要在 Header 中的提交按钮和 Form 组件的提交方法之间进行通信。我知道进行父>子或子>父通信很简单,但在这种情况下,我的 Header 和 Form 组件之间没有父子关系或兄弟关系。

我的组件树如下所示:

- app-root
  |-- app-header // -> this is where the submit button is
  |-- app-edit-profile
      |-- app-profile-form // -> this is my form

有人知道可能的实现吗?

【问题讨论】:

    标签: angular


    【解决方案1】:

    您可以创建一个在您的标头和表单组件之间共享的服务,您可以在其中定义Observable,以便您可以从表单订阅Observable,并在您从标头收到一些值时执行一些操作。

    common.service.ts

    import { Injectable, Inject } from '@angular/core';
    import { Subject }    from 'rxjs/Subject';
    @Injectable()
    export class CommonService {
      private notify = new Subject<any>();
      /**
       * Observable string streams
       */
      notifyObservable$ = this.notify.asObservable();
    
      constructor(){}
    
      public notifyOther(data: any) {
        if (data) {
          this.notify.next(data);
        }
      }
    }
    

    header.component.ts

    import { Component, OnInit, OnDestroy } from '@angular/core';
    import { Subscription } from 'rxjs/Subscription';
    
    import { CommonService } from './common.service';
    
    @Component({
      selector   : 'header',
      templateUrl : './header.html'
    })
    export class HeaderComponent implements OnInit, OnDestroy {
      constructor( private commonService: CommonService ){
      }
    
      ngOnInit() {       
      }
    
      onSubmit(){
        // this method needs to be called when user click on submit button from header
        this.commonService.notifyOther({option: 'onSubmit', value: 'From header'});
      }
    }
    

    form.component.ts

    import { Component, OnInit, OnDestroy } from '@angular/core';
    import { Subscription } from 'rxjs/Subscription';
    
    import { CommonService } from './common.service';
    
    @Component({
      selector   : 'form',
      templateUrl : './form.html'
    })
    export class FormComponent implements OnInit, OnDestroy {
      private subscription: Subscription;
      constructor( private commonService: CommonService ){
      }
    
      ngOnInit() {
        this.subscription = this.commonService.notifyObservable$.subscribe((res) => {
          if (res.hasOwnProperty('option') && res.option === 'onSubmit') {
            console.log(res.value);
            // perform your other action from here
    
          }
        });
      }
    
      ngOnDestroy() {
        this.subscription.unsubscribe();
      }
    }
    

    【讨论】:

    • 我已经编辑了我的帖子以添加我的组件树,正如我所说的两个组件之间没有父/子关系。但是,我会尝试您的解决方案,因为我猜无论关系如何,都可以共享服务。谢谢!
    • 您需要在主模块的providers 配置中声明CommonService,以便在标题和表单组件之间共享单个实例。
    • 是的,我想通了,它就像一个魅力 :) 谢谢!
    • 需要在common.services.ts中加入这个:import { Observable } from "rxjs/Observable";
    【解决方案2】:

    除了使用 Observable 的解决方案之外,我认为有必要谈谈 EventEmitters,因为在我看来,它们在这种情况下更易于使用。

    在子控制器中

    导入 EventEmitter 和输出类型。

    import { EventEmitter, Output } from "@angular/core

    声明一个 EventEmitter 类型的输出属性

    @Output() formSubmit$: EventEmitter&lt;boolean&gt;;

    记得在构造函数中初始化EventEmitter,如下:

    this.formSubmit$ = new EventEmitter();

    最后,通过绑定到提交按钮的正确操作,触发 EventEmitter “emit” 方法在您的应用中传播事件:

    this.formSubmit$.emit(true);

    在父控制器中

    在父视图中,将 formSubmit$ 事件绑定到控制器的一个动作:

    &lt;child-selector (formSubmit$)="handleFormSubmit($event)"&gt;&lt;/child-selector&gt;

    然后在Controller中声明方法

    public handleFormSubmit(submit: boolean): void {
        alert("Form has been submitted! Do your stuff here!");
    }
    

    显然,这种策略仅在需要从子控制器交换数据到父控制器时使用。

    【讨论】:

      【解决方案3】:

      父母和孩子通过服务进行交流

      Angular2 call method of other component

      【讨论】:

      • 请添加一些关于您的链接在做什么的解释。链接可能会消失,因此,如果出现这种情况,这个答案将毫无价值。
      【解决方案4】:

      使用服务和主题是最简单的方法。如果你想记录你的数据,你甚至可以使用回放主题

      private notify: ReplaySubject<any> = new ReplaySubject<any>();
      

      但是,您甚至可以尝试一个名为 eventbus 的库。我遇到了同样的问题,而 eventbus 正是这个问题的正确答案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多