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

时间:2018-01-10 19:52:31

标签: javascript angular

我的角度应用程序上有一个外部js库,我在angular-cli.json脚本数组中将其添加为全局脚本。它的工作正常,但我需要指定一些函数作为对这个库的事件的响应。这个库有一个Display对象,它有一些事件:

Display.onplay
Display.onpause

如何在我的angular component.ts中听这些事件?

在普通的javascript Web应用程序中,只需将其分配给以下函数:

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

但在角度上,我不知道是否有可能这样做。

2 个答案:

答案 0 :(得分:3)

从Angular应用程序访问外部Javascript库是可能的,也是适当的。但是要记住一些问题。

类型声明

  

如果我在打字稿中打字,我会得到一些编译错误。

这在Typescript中很常见。有几种方法可以解决这个问题。

第一种(也可能是最好的)方法是为项目中的Display库包含一个Typescript类型声明(.d.ts)文件。如果这是一个受欢迎的第三方库,它可能已经作为名为@ types / [PACKAGE_NAME]的npm包提供。如果它不可用,您可以编写类型声明。有关创建和包含类型声明的更多信息,请参阅Typescript Documentation

第二种方法是简单地使用(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;
    }
}

答案 1 :(得分:1)

使用服务和可观察服务的另一个方法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 
        })
      }
    });
相关问题