[英]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.