简体   繁体   English

Angular2:如何从子组件调用主组件函数

[英]Angular2 : how to call main component function from a child component

How to call main component function from a child component when I have deep nested hierarchy? 当我有深层嵌套层次结构时,如何从子组件调用主组件功能?

在此输入图像描述

I have 3 components, button component I'm including inside browser component and browser component I'm including inside main component. 我有3个组件,按钮组件我包括浏览器组件和浏览器组件我包括在主要组件内。

On click of button I need to call a function which is inside main component. 点击按钮我需要调用主要组件内的功能。

Button Component 按钮组件

@Component({
    selector: 'cb-button',
    templateUrl: 'cb-button.component.html',
    styleUrls: ['cb-button.component.scss']
})

export class CbButtonComponent {

     @Output() onClick: EventEmitter<any> = new EventEmitter();

     onBtnClick(): void {
        this.onClick.emit();
    }
}

button component html 按钮组件html

<div (click)="onBtnClick()">
    <button>btn</button>
</div>

browser component 浏览器组件

@Component({
    selector: 'topology-browser',
    templateUrl: 'topology-browser.component.html',
    styleUrls: ['topology-browser.component.scss']
})

export class TopologyBrowserComponent {

   @Input('campus') campus: Campus;
}

browser component html 浏览器组件html

<div>
<h1>browser title</h1>
<cb-button (click)="editCampus()"></cb-button>
</div>

and finally in main component i'm including browser component 最后在主要组件中我包括浏览器组件

main-component.ts 主component.ts

editCampus() {
  alert('clicked');
}

html HTML

<topology-browser [campus]="campus"></topology-browser>

when I click button I'm getting below error 当我点击按钮时,我收到以下错误

Errorself.parentView.context.editCampus is not a function Errorself.parentView.context.editCampus不是一个函数

  • If you know what type the root component is, you can use Pengyy's method. 如果您知道根组件的类型,可以使用Pengyy的方法。
  • If you don't know what type in advance but you can customize the root component to your needs, a shared service is a good way. 如果您事先不知道什么类型,但您可以根据需要自定义根组件,则共享服务是一种好方法。

  • A more generic way is to get the root component by injecting ApplicationRef (not actually tested myself): 更通用的方法是通过注入ApplicationRef来获取根组件(实际上没有自己测试过):

constructor(app:ApplicationRef, injector: Injector) {
  app.components[0].someMethodOnMainComponent();
}

https://angular.io/docs/ts/latest/api/core/index/ApplicationRef-class.html https://angular.io/docs/ts/latest/api/core/index/ApplicationRef-class.html

As I know there are two ways for your situation: 据我所知,您的情况有两种:

  • inject the parent component to child component inject父组件inject子组件
  • use EventEmitter 使用EventEmitter

Since you have more than two layers, injecting MainComponent to ButtonComponent is much more simply to implement: 既然你有两个以上的层,注射MainComponentButtonComponent是更简单的实现:

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

// change the MainComponent to your real component name
constructor(@Inject(forwardRef(() => MainComponent)) private main:MainComponent)
export class CbButtonComponent {

     @Output() onClick: EventEmitter<string> = new EventEmitter<string>();

     onBtnClick(): void {
        this.onClick.emit('clicked');
    }
}

In your browser component 在您的浏览器组件中

HTML HTML

<div>
    <h1>browser title</h1>
    <cb-button (onclick)="buttonclicked($event)"></cb-button>
</div>

Component 零件

@Output() buttonClick: EventEmitter<string> = new EventEmitter<string>();

buttonclicked(clickedEvent){
   this.buttonClick.emit('clicked');
}

In your parent Main component 在您的父主组件中

<topology-browser [campus]="campus" (buttonClick)="buttonComponentClicked($event)"></topology-browser>

Component code 组件代码

buttonComponentClicked(buttonClicked){
       /// method calls goes her

}

By this way you are notifying the browser component with the click which is captured again in the main component and handled 通过这种方式,您将通过在主组件中再次捕获并处理的点击通知浏览器组件

You may try the below. 您可以尝试下面的内容。 I have not tried this but am guessing it might work. 我没试过这个,但我猜它可能有用。 The button component emits an event which is being caught by the main component. 按钮组件发出主要组件捕获的事件。

You may also pass data via a common service and injecting that service into the child component and calling a service function which updates a service observable which is subscribed by the main component 您还可以通过公共服务传递数据并将该服务注入子组件并调用服务函数,该服务函数更新主要组件订阅的服务可观察对象

Your main component 你的主要成分

@Component({
  template `
    <button-comp (onClick)="mainMethod($event)"></button-comp>
  `,
  directives: [ ButtonComponent ]
})
export class MainComponent {
  (...)

  mainMethod(event) {
    console.log(event)
  }
}

your button component 你的按钮组件

@Component({
    selector: 'cb-button',
    templateUrl: 'cb-button.component.html',
    styleUrls: ['cb-button.component.scss']
})

export class CbButtonComponent {

     @Output() onClick: EventEmitter<any> = new EventEmitter();

     onBtnClick(): void {
        this.onClick.emit('hello');
    }
}

button component html

<div (click)="onBtnClick()">
    <button>btn</button>
</div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM