在对话框中打开时,角垫滑块的动画从100变为0

时间:2019-06-22 13:56:23

标签: angular angular-material

我有一个在对话框中打开的角度组件。 我的防滑垫定义如下:

<mat-slider min="0" max="100" [value]="progressBarValue" (change)="changeProgress($event)"></mat-slider>

但是,当我打开对话框时,即使我已经在构造函数中设置了progressBarValue = 0,mat滑块的进度值也会从100动画为0。

我不知道为什么。我在模板中显示相同内容的其他组件没有这种问题。

有人遇到过这种行为吗?enter image description here

我希望它在动画从100到0时为0。请参见gif的结尾。

我将源代码最小化如下,仍然存在相同的问题

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-insert',
  templateUrl: './insert.html',
  styleUrls: ['./insert.scss']
})
export class InsertComponent implements OnInit {

    progressBarValue: number;

    constructor() {
        this.progressBarValue = 0;
    }

    ngOnInit() {
    }

}

在组件html中

<mat-slider min="0" max="100" [value]="progressBarValue"></mat-slider>

在另一个组件中,在对话框中启动上述组件

        const dialog = {
           currentTime: 0
        };
        const dialogRef = this.dialog.open(InsertComponent, {
            panelClass: 'app-dialog',
            data: dialog,
            autoFocus: false
        });
        dialogRef.afterClosed().subscribe((currentTime) => {
        });

如果有人知道为什么会发生这种情况,请告诉我。非常感谢。

2 个答案:

答案 0 :(得分:0)

属性指令ngStyle与指定的功能结合使用,这些功能会在mat-slider的多个不同元素上使用,每次滑块值更改时都会触发CSS转换:

<!-- slider html template excerpt -->
<div class="mat-slider-wrapper" #sliderWrapper>
  <div class="mat-slider-track-wrapper">
    <div class="mat-slider-track-background" [ngStyle]="_trackBackgroundStyles"></div>
    <div class="mat-slider-track-fill" [ngStyle]="_trackFillStyles"></div>
  </div>
  ...
</div>
// slider component excerpt
get _trackBackgroundStyles(): { [key: string]: string } {
    const axis = this.vertical ? 'Y' : 'X';
    const scale = this.vertical ? `1, ${1 - this.percent}, 1` : `${1 - this.percent}, 1, 1`;
    const sign = this._shouldInvertMouseCoords() ? '-' : '';

    return {
      // scale3d avoids some rendering issues in Chrome. See #12071.
      transform: `translate${axis}(${sign}${this._thumbGap}px) scale3d(${scale})`
    };
  }
...

(请参阅完整资料:MatSlider html sourceMatSlider ts source)。

由于如何实例化组件并将其注入对话框,在初始化过程中在此处触发了转换。因此,为了实现所需的行为,需要(暂时)禁用CSS动画。

一种解决方案(可能非常hacky,但可行)是通过向mat-slider添加一个类来禁用动画,这将删除过渡并在初始化完成后删除该类:

<!-- insert.component.html -->
<mat-slider [ngClass]="{'disableAnimation':isAnimationDisabled}" min="0" max="100" [(ngModel)]="progressBarValue" (change)="changeProgress($event)"></mat-slider>
/* insert.component.css */
::ng-deep .disableAnimation *{
 transition: none !important;
}
// insert.component.ts
...

@Component({
  ...
})
export class InsertComponent implements AfterViewInit {
  ...  
  isAnimationDisabled: boolean = true;

  ...

  ngAfterViewInit() {
    setTimeout(() => {
      this.isAnimationDisabled = false;
    })
  }
}

由于在此示例中初始化过程非常快速地完成,因此您需要使用setTimeout,否则将获得ExpressionChangedAfterItHasBeenCheckedError。为了防止这种情况,您还可以将ChangeDetectionStrategy更改为OnPush,并在初始化完成后手动触发更改检测。

我已经创建了一个Stackblitz供您玩耍。

答案 1 :(得分:0)

要专门针对初始化时垫式滑块上的幻灯片动画,您可以覆盖该css的过渡。

.mat-slider {
     .mat-slider-thumb-container {
         transition: none;
     }
}

放置在组件或全局样式表中。