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

How to execute a function from another component that is NOT a sibling of the first component?

我正在尝试从另一个组件执行功能(这 2 个组件不是兄弟组件)。我的猜测是我将需要使用 @Output 和 eventEmitter 来完成此操作或创建一个 Service 并订阅 Observable 在所有组件中共享相同的数据(我知道如何传递消息(字符串)但我不知道如何执行函数)。我不太确定从哪里开始。我正在尝试从 function2 执行 function1。谁能帮我解决这个问题? 请提供一个插件。这是我的项目的样子:

   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!!");
                                         }

如您所见,我有一个包含 function2 的文件 home.component.ts 和一个包含 function2 的文件 tools.component.ts function1,那么关于如何从 function2 执行 function1 有什么想法吗?

继承组件。

假设一个组件。

@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();
}

此外,请记住,如果您使用 angular,则需要在 declarationsentryComponents 中导出您的组件。您还需要将其导入到您的新组件中。

import { Component1 } from 'directory/component';

/* 示例 */

import { SplashScreen } from 'directory/splash-screen';

使用服务。在您的 home.component 中订阅服务的 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");

题目是execute a function,可以用这个思路,做一些像

//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;
      ....
   }
}

根据您要执行的操作,您有两种选择。

首先:如果你需要Angular特性(例如依赖注入)或者想要共享数据,你应该考虑使用服务。已经有足够多的文档和教程(请参阅 angular docs。)我建议您通读这篇文章。

其次: 如果您只需要 JavaScript 功能,您可以创建一个 TypeScript 文件(例如 /src/app/shared/tools.ts 并将您的方法放在那里。这是主要用于执行某种计算、格式化或类似操作的静态函数。然后您可以在任何需要的地方导入和使用该函数。(提示:制作它 pure。)

我同意你关于带有可观察对象的服务的想法是你最好的选择(正如其他人所建议的那样)——尽管在这种情况下我更喜欢 BehaviorSubject。这是一个简单的工作 plunkr,演示了如何实现它:

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;
 }
}

第一组件

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.'
  }
}

第二分量

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 + '"';
  }
}