如何从不是第一个组件的兄弟的另一个组件执行一个函数?

时间:2018-01-03 00:11:14

标签: angular typescript angular-components

我试图从另一个组件执行一个函数(这两个组件不是兄弟姐妹)。我的猜测是我需要使用 @Output和eventEmitter 来完成此操作或创建服务并订阅 Observable 以共享相同内容所有组件中的数据(我知道如何传递消息(字符串),但我不知道如何执行一个函数)。我不确定从哪里开始。我试图执行 function1 FROM function2 。任何人都可以帮助我如何让这个工作? 请提供一名探索者。这就是我的项目:

   src
   |__app(FOLDER)
      |__home(FOLDER)
      |     |
      |     |__home.component.ts 
      |                  |______function2(){
      |                          What do I need to put in here to execute function1?
      |                          }
      | 
      |__products(FOLDER) 
           |
           |__tools(FOLDER)
                  |
                  |____tools.component.ts
                                   |____function1(){
                                         alert("I'm inside function 1!!");
                                         }

如您所见,我有一个文件 home.component.ts ,其中包含function2和一个包含function1的文件 tools.component.ts ,所以任何想法如何执行function1来自function2?

4 个答案:

答案 0 :(得分:3)

我同意您对具有可观察性的服务的想法是您最好的选择(正如其他人所建议的那样) - 尽管在这种情况下我更喜欢BehaviorSubject。这是一个简单,有效的插件,演示了如何实现这一点:

https://plnkr.co/edit/quHc2yOkxXIbXYUlnZbB?p=preview

如果我们细分了这个要求,那么你需要的是一个只传递事件的事件代理服务。这个plunkr也能够通过服务传递一个参数对象 - 如果你需要这样做 - 但如果没有,那么只需传递你想要的任何对象(或者只是从所有方法中删除param个参数) 。

此实现并不关心组件不是兄弟 - 因为我们正在使用服务。无论您的应用程序结构如何,两者都将提供相同的服务实例。

为了快速参考,以下是重要的代码:

<强> EventProxyService

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

@Injectable()
export class EventProxyService {

 private eventSubject = new BehaviorSubject<any>(undefined);

 triggerSomeEvent(param: any) {
     this.eventSubject.next(param);
 }

 getEventSubject(): BehaviorSubject<any> {
    return this.eventSubject;
 }
}

<强> FirstComponent

import { Component, OnInit } from '@angular/core';
import { EventProxyService } from './event-proxy.service';

@Component({
  selector: 'app-first',
  templateUrl: './src/first.component.html'
})
export class FirstComponent implements OnInit {
  displayText = 'I havent created any events yet.';
  constructor(private eventProxyService: EventProxyService) { }

  ngOnInit() { }

  triggerAnEvent() {
    this.eventProxyService.triggerSomeEvent(Date());
    this.displayText = 'I fired an event.'
  }
}

<强> SecondComponent

import { Component, OnInit } from '@angular/core';
import { EventProxyService } from './event-proxy.service';

@Component({
  selector: 'app-second',
  templateUrl: './src/second.component.html'
})
export class SecondComponent implements OnInit {

  displayText = 'I havent got an event yet';
  constructor(private eventProxyService: EventProxyService) { }

  ngOnInit() {
    this.eventProxyService.getEventSubject().subscribe((param: any) => {
      if (param !== undefined) {
        this.theTargetMethod(param);
      }
      });
  }

  theTargetMethod(param) {
    this.displayText = 'Target Method got called with parameter: "' + param + '"';
  }
}

答案 1 :(得分:1)

使用服务。在home.component中订阅服务的Observable并从工具中执行observable的更改

//Your service
private dataSource = new Subject<any>();
data = this.searchDataSource.asObservable();
change(param:any) {
   this.searchDataSource.next(param)
}
//Your home.component
this.myService.data.subscribe((param: any) => {
      console.log(param)
}
//Your tool
this.myService.change("Hello world");

由于问题是执行一个函数,你可以使用这个想法,做一些像

//Your tool:
    this.myService.change("Command1") 
//or even
    this.myService.change({"command":"Command1","arg":myvariable})

//Your home.component
this.myService.data.subscribe((param:any)=>
{  switch (param.command)
   {
      case "Command1":
          this.function1(param.arg);
          break;
      case "Command2":
          this.function2();
          break;
      ....
   }
}

答案 2 :(得分:0)

根据您的目的,您有两种选择。

首先:如果您需要Angular功能(例如依赖注入)或想要共享数据,您应该考虑使用服务。已经有足够的文档和教程(参见angular docs。)我建议你仔细阅读。

第二:如果您只需要JavaScript功能,您可以创建一个TypeScript文件(例如/src/app/shared/tools.ts并将您的方法放在那里。这对于某些类型的静态函数非常有用计算,格式化或类似。然后,您可以在任何需要的地方导入和使用该功能。(提示:将其设为pure。)

答案 3 :(得分:-1)

继承组件。

让我们说一个组件。

children

您可以@Component({ ... }) export class Component1 { constructor(); public test1() { console.log("this is a test"); } } 作为孩子的第一个组件执行inheritance方法

test1

此外,请记住,如果您使用角度,则需要在@Component({ ... }) export Class Component2 extends Component1 { constructor(); //Execute test1 method test1(); } declarations中导出组件。您还需要在新组件中导入它。

entryComponents

/ *示例* /

import { Component1 } from 'directory/component';