網站搜尋

angular - 如何從另一個不是第一個元件的兄弟元件執行函數?


我正試圖從另一個元件執行一個函數(這兩個元件不是同級)。我猜我需要使用 @Output 和 eventEmitter 來完成這個,或者建立一個 Service 並訂閱 Observable,以便在所有元件之間共享相同的資料(我知道如何傳遞訊息(字串),但我不知道如何執行函數)。我真的不確定從哪裡開始。我正試圖從 function2 執行 function1。有人可以幫我看看怎麼做到這點嗎?請提供一個 plunker 範例。這是我的專案樣子:

   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,還有一個檔案 tools.component.ts,其中有 function1,所以有什麼方法可以從 function2 執行 function1 嗎?

答案#1

我同意你關於使用可觀察對象的服務的想法是你在這裡的最佳選擇(正如其他人所建議的)——雖然在這種情況下我更偏好使用BehaviorSubject。這裡有一個簡單、可運行的 Plunkr,示範你如何實作這個功能:

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

如果我們拆解這個需求,你在這裡需要的是一個事件代理服務,它只是轉發事件。這個 plunkr 也能夠通過服務傳遞一個參數對象——如果你需要這樣做——但如果不需要,那就隨意傳遞任何對象(或者乾脆從所有方法中完全移除 param 參數)。

這個實作不在乎組件不是同級的——因為我們使用的是服務。不管你的應用結構如何,兩者都會提供相同的服務實例。

為了快速參考,這裡是重要的程式碼片段:

事件代理服務

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

答案#2

根據你想做的事情,你有兩個選擇。

首先: 如果你需要 Angular 的功能(例如依賴注入)或想共享數據,你應該考慮使用服務。已有足夠的文檔和教程(參見 Angular 文檔)。我建議仔細閱讀這些內容。

第二: 如果你只需要 JavaScript 功能,你可以創建一個 TypeScript 文件(例如 /src/app/shared/tools.ts)並將你的方法放在那裡。這主要適用於執行某種計算、格式化或類似操作的靜態函數。然後你可以在需要的地方導入並使用該函數。(提示:保持純函數。)