簡體   English   中英

Angular 在對話框中打開時,mat-slider 動畫從 100 到 0

[英]Angular mat-slider animate from 100 to 0 when opening in the dialog

我有在對話框中打開的 angular 組件。 我的 mat-slide 定義如下:

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

但是當對話框打開時,mat slider 進度值從 100 變為 0,即使我已經在構造函數中設置了 progressBarValue=0。

我不知道為什么。 我在模板中顯示相同內容的其他組件沒有此類問題。

有人遇到過這種行為嗎? 在此處輸入圖像描述

我希望它在 0 沒有 animation 從 100 到 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) => {
        });

如果有人知道為什么會這樣,請告訴我。 非常感謝。

屬性指令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 源代碼MatSlider ts 源代碼)。

由於組件實例化和注入對話框的方式,在初始化過程中會在此處觸發轉換。 因此,為了實現您想要的行為,需要(暫時)禁用 CSS 動畫。

一個(可能非常笨拙但有效)的解決方案是通過向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供你玩。

要在初始化時專門針對 mat-slider 上的幻燈片動畫,您可以只覆蓋那段 css 的過渡。

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

放置在您的組件或全局樣式表中。

使用 EventEmitter 我們可以解決這個問題

HTML 檔案:

  <div class="price-slider-wrapper" lines="none">
       <ng5-slider color="primary" [(value)]="minPrice" [(highValue)]="maxPrice" 
                      (userChange)="priceSliderChange($event)"
             [options]="premoptions" (click)="$event.stopPropagation();"  [manualRefresh]="manualRefresh">
      </ng5-slider>
 </div> 

TS文件:

  public manualRefresh = new EventEmitter<void>();
 priceMenuOpen:boolean = false;

  openPriceSlider(){
        this.priceMenuOpen = true;
        setTimeout(() => {
            this.manualRefresh.emit();
        }, 200);
    }

在名為 openPriceSlider() 的菜單單擊事件上 function:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM