[英]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.