簡體   English   中英

如何在角度應用程序上收聽外部js事件?

[英]How to listen to an external js event on angular app?

我的角度應用程序上有一個外部js庫,我在angular-cli.json腳本數組中添加了它作為全局腳本。 它的工作正常,但我需要指定一些函數作為對這個庫的事件的響應。 這個庫有一個Display對象,它有一些事件:

Display.onplay
Display.onpause

我怎樣才能在我的角度組件中聽這些事件。

在普通的javascript Web應用程序只是將它分配給一個函數,如:

  Display.onplay = function () { console.log('play'); }

但在角度上,我不知道它是否有可能做到這一點。

從Angular應用程序訪問外部Javascript庫是可能的,也是適當的。 但是要記住一些問題。

鍵入聲明

如果我在打字稿中打字,我會得到一些編譯錯誤。

這在Typescript中很常見。 有幾種方法可以解決這個問題。

第一種(也可能是最好的)方法是為項目中的Display庫包含Typescript類型聲明(.d.ts)文件。 如果這是一個受歡迎的第三方庫,它可能已經作為名為@ types / [PACKAGE_NAME]的npm包提供。 如果它不可用,您可以編寫類型聲明。 有關創建和包含類型聲明的更多信息,請參見Typescript文檔

第二種方法是簡單地使用(Display as any).onplay(Display as any).onpause避免編譯錯誤。

單元測試

將此代碼放在頂級組件中可能足以滿足您的需求,但我對此表示懷疑。 這限制了可以使用Display庫的位置。

我建議將圖書館包裝在精心設計的服務中。 使用服務允許多個組件/服務訪問Display庫。

您可能會對依賴於Display庫的代碼進行單元測試。 如果是這種情況,適當的使用場所(Display as any).onplay = ...肯定會在服務中。 服務可以更容易地保留第三方庫的功能。

這是一個未經測試的示例服務:

import { Injectable } from '@angular/core';

export interface IDisplayService {
    onPlay(callback: () => void): void;
    onPause(callback: () => void): void;
}

@Injectable()
export class DisplayService implements IDisplayService {
    private onPlayCallback: () => void;
    private onPauseCallback: () => void;

    constructor() {
        if (!Display) {
            throw new Error('Display library is required');
        }

        (Display as any).onplay = () => {
            if (this.onPlayCallback) { this.onPlayCallback(); }
        };
        (Display as any).onpause = () => {
            if (this.onPauseCallback) { this.onPauseCallback(); }
        };
    }

    // Using a function allows you to register multiple callbacks
    // if you choose to allow it later on.
    onPlay(callback: () => void): void {
        this.onPlayCallback = callback;
    }

    onPause(callback: () => void): void {
        this.onPauseCallback = callback;
    }
}

另一個aproach使用服務和可觀察的服務和app.component中的代碼

app.component

declare var Display:any //<--declare the variable
@component(..)

export class AppComponent {
  constructor(private outEventService:OutEventService) {
  }
  Display.onplay (){   //the function like javascript only call function of service
     this.outEventService.sendEvent("play");
  }
  Display.onpause (){
     this.outEventService.sendEvent("pause");
  }
}

outEventService

export class OutEventService{

    private listeningSource:Subject<any>=new Subject<any>();
    displayEvent:Observable<any>=this.listeningSource.asObservable();

    constructor() {
    }

    sendEvent(evento:any)  //Simply make a change in the observable
    {
        this.listeningSource.next(evento);
    }
}

訂閱事件的組件

constructor(private ngZone: NgZone,
    private outEventService: outEventService) {
  }
ngOnInit() {
this.outEventService.displayEvent.subscribe((evento: any) => {
      if (evento == "pause") {  
           do something
      }
      if (evento == "other") {  //Sometimes you must use ngZone to angular take account the change
        this.ngZone.run(() => {
            do something 
        })
      }
    });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM