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 结构来根据动画的当前状态(停止、完成、暂停、运行)切换按钮的外观。这是由布尔变量 isPausedisPlaying 以类似的方式处理的:

<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);
    }
}