angular 2: ngIf 问题
angular 2: ngIf problems
我有一个 angular 2 项目,其中 canvas class(构建在打字稿中,但在实际 angular 2 应用程序之外)每当当前canvas 上的动画已完成。这是由以下基本事件 listener/dispatcher 结构执行的:
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;
}
由于 canvas 所在的组件和动画完成后应更新视图的组件是兄弟组件,因此 canvasHelperService
处理这两者的通信。
在监听组件中有一个 ngIf 结构来根据动画的当前状态(停止、完成、暂停、运行)切换按钮的外观。这是由布尔变量 isPaused
和 isPlaying
以类似的方式处理的:
<span *ngIf="!isPlaying" (click)="play()">PLAY ICON</span>
<span *ngIf="isPlaying" (click)="pause()">PAUSE ICON</span>
如果这些都重置为 false
,则应恢复初始状态。这一切实际上都很好。但是,它只会在我将鼠标悬停在 canvas 上时立即重置按钮以显示播放图标,我找不到发生这种情况的原因。
如何强制 ngIf 立即对当前动画状态做出反应,而无需将鼠标悬停在 canvas(调度事件的组件的一部分)上?
我猜变化检测对你来说不合适。 animationFinished
事件可能未在正确的 NgZone 中调度。要解决此问题,您可以使用 NgZone.run,如下所示:https://angular.io/docs/ts/latest/api/core/index/NgZone-class.html
ngOnInit() {
this.canvasHelper.addEventListener('animationFinished', () =>
this._ngZone.run(() => this.handleAnimationEnd()));
}
}
或者检查您的事件分发器是否在 NgZone 中创建(通常是通过 angular2 依赖注入机制创建的)。
我认为问题在于,当使用 $.each
时,您的事件侦听器回调在 NgZone
中不是 运行。您可以使用默认的 Array.prototype.foreach
来循环监听器:
this.eventListener.forEach(listener => {
if(listener.name == name) {
listener.cb(event);
}
}
我有一个 angular 2 项目,其中 canvas class(构建在打字稿中,但在实际 angular 2 应用程序之外)每当当前canvas 上的动画已完成。这是由以下基本事件 listener/dispatcher 结构执行的:
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;
}
由于 canvas 所在的组件和动画完成后应更新视图的组件是兄弟组件,因此 canvasHelperService
处理这两者的通信。
在监听组件中有一个 ngIf 结构来根据动画的当前状态(停止、完成、暂停、运行)切换按钮的外观。这是由布尔变量 isPaused
和 isPlaying
以类似的方式处理的:
<span *ngIf="!isPlaying" (click)="play()">PLAY ICON</span>
<span *ngIf="isPlaying" (click)="pause()">PAUSE ICON</span>
如果这些都重置为 false
,则应恢复初始状态。这一切实际上都很好。但是,它只会在我将鼠标悬停在 canvas 上时立即重置按钮以显示播放图标,我找不到发生这种情况的原因。
如何强制 ngIf 立即对当前动画状态做出反应,而无需将鼠标悬停在 canvas(调度事件的组件的一部分)上?
我猜变化检测对你来说不合适。 animationFinished
事件可能未在正确的 NgZone 中调度。要解决此问题,您可以使用 NgZone.run,如下所示:https://angular.io/docs/ts/latest/api/core/index/NgZone-class.html
ngOnInit() {
this.canvasHelper.addEventListener('animationFinished', () =>
this._ngZone.run(() => this.handleAnimationEnd()));
}
}
或者检查您的事件分发器是否在 NgZone 中创建(通常是通过 angular2 依赖注入机制创建的)。
我认为问题在于,当使用 $.each
时,您的事件侦听器回调在 NgZone
中不是 运行。您可以使用默认的 Array.prototype.foreach
来循环监听器:
this.eventListener.forEach(listener => {
if(listener.name == name) {
listener.cb(event);
}
}