我有一个角度2项目,其中画布类(构建在typescript中但在实际的角度2应用程序之外)在画布上的当前动画完成时触发事件。这由以下基本事件监听器/调度程序结构执行:
canvas.ts
eventListener = [];
public addListener(name : string, cb : Function) {
this.eventListener.push({name: name, cb : cb});
}
public dispatchEvent(name : String, event) {
var scope = this;
$.each(scope.eventListener, function(key, value){
if(value.name == name) {
value.cb(event);
}
});
}
事件监听器在一个组件中注册:
组件 - 即-listens.ts
ngOnInit() {
this.canvasHelper.addEventListener('animationFinished', () => this.handleAnimationEnd());
}
private handleAnimationEnd() {
this.isPlaying = false;
this.isPaused = false;
}
作为画布所在的组件,当动画完成时应该更新视图的组件是同级组件,有canvasHelperService
处理这两者的通信。
在监听组件中,有一个ngIf结构,用于根据动画的当前状态切换按钮的外观(停止,完成,暂停,运行)。这由布尔变量isPaused
和isPlaying
以类似的方式处理:
<span *ngIf="!isPlaying" (click)="play()">PLAY ICON</span>
<span *ngIf="isPlaying" (click)="pause()">PAUSE ICON</span>
如果这些都重置为false
,则应恢复初始状态。这一切实际上都很好。但是,只有当我将鼠标悬停在画布上时,它才会重置按钮以显示播放图标,但我无法找到导致此情况发生的原因。
如何强制ngIf立即对当前动画状态做出反应而不必将鼠标悬停在画布上(调度事件的组件的一部分)?
答案 0 :(得分:1)
我认为更改检测对您来说不合适。可能无法在正确的NgZone中调度animationFinished
事件。要解决此问题,您可以使用NgZone.run,如下所示:https://angular.io/docs/ts/latest/api/core/index/NgZone-class.html
ngOnInit() {
this.canvasHelper.addEventListener('animationFinished', () =>
this._ngZone.run(() => this.handleAnimationEnd()));
}
}
或者检查你的eventdispatcher是在NgZone中创建的(通常是通过angular2依赖注入机制创建它)。
答案 1 :(得分:0)
我认为问题是,使用NgZone
时,您的事件监听器回调未在$.each
中运行。您可以使用默认的Array.prototype.foreach
来循环监听器:
this.eventListener.forEach(listener => {
if(listener.name == name) {
listener.cb(event);
}
}