我的角度应用程序上有一个外部js库,我在angular-cli.json脚本数组中将其添加为全局脚本。它的工作正常,但我需要指定一些函数作为对这个库的事件的响应。这个库有一个Display
对象,它有一些事件:
Display.onplay
Display.onpause
如何在我的angular component.ts中听这些事件?
在普通的javascript Web应用程序中,只需将其分配给以下函数:
Display.onplay = function () { console.log('play'); }
但在角度上,我不知道是否有可能这样做。
答案 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
})
}
});