问题描述
我需要动态更改角度材质进度条的颜色.我意识到事情没那么简单,那么最好的方法是什么?
I need to change the color of angular material progress bar dynamically.I realized that it is not that simple, so what is the best way to to it?
要求:
- 我将从外部 API 接收颜色十六进制代码.所以我不能创建一组预定义的主题
- 背景颜色将为白色.所以,我只需要一种颜色,而不是整个调色板(较浅、较深)的颜色.
相关链接:(1)
推荐答案
我们可以创建一个属性指令,它接受颜色值并为我们覆盖 的默认样式.
We can create an attribute directive which accepts the color value and override default styles of <mat-progress-bar>
for us.
这是一个工作演示:https://stackblitz.com/edit/材料进度条颜色指令
这里是一个简单的解释:
here is a brief explanation:
如果我们在开发者工具中检查 .我们会发现进度条的颜色是在
::after
伪元素中定义的,就像这样.
If we inspect <mat-progress-bar>
in developer tools. we will find that color of the progress-bar is defined in the ::after
pseudo element like this.
.mat-progress-bar-fill::after {
background-color: #3f51b5;
}
正如我们已经知道的那样,不可能使用 DOM querySelector() 方法直接操作一个伪元素.但是我们可以添加新的样式,这些样式也可以包含伪元素的规则.查看此线程以获取更多详细信息.https://stackoverflow.com/a/21709814/1160236
And as we already know that it is not possible to directly manipulate a pseudo element using DOM querySelector() method. But we can add new styles which can have rules for pseudo elements too. checkout this thread for more details. https://stackoverflow.com/a/21709814/1160236
所以,我们可以制定一个指令来为我们添加新的样式.
So, we can make a directive which can take care of adding new styles for us.
import { Directive, Input, OnChanges, SimpleChanges, ElementRef } from '@angular/core';
@Directive({
selector: '[appProgressBarColor]'
})
export class ProgressBarColor implements OnChanges{
static counter = 0;
@Input() appProgressBarColor;
styleEl:HTMLStyleElement = document.createElement('style');
//generate unique attribule which we will use to minimise the scope of our dynamic style
uniqueAttr = `app-progress-bar-color-${ProgressBarColor.counter++}`;
constructor(private el: ElementRef) {
const nativeEl: HTMLElement = this.el.nativeElement;
nativeEl.setAttribute(this.uniqueAttr,'');
nativeEl.appendChild(this.styleEl);
}
ngOnChanges(changes: SimpleChanges): void{
this.updateColor();
}
updateColor(): void{
// update dynamic style with the uniqueAttr
this.styleEl.innerText = `
[${this.uniqueAttr}] .mat-progress-bar-fill::after {
background-color: ${this.appProgressBarColor};
}
`;
}
}
如您所见,我们在这里所做的只是创建一个新的 HtmlStyleElement
并将其添加到宿主元素中.
as you can see that all that we are doing here is just making a new HtmlStyleElement
and adding it just inside the host element.
在 updateColor()
方法中,我们正在更新我们附加的样式标签的 innerText
.请注意,我们在这里使用了一个带有唯一属性的属性选择器,以将样式的范围仅用于宿主.因为我们只想为应用了指令的进度条覆盖样式.
And inside updateColor()
method we are updating the innerText
of the style tag we have appended. notice that we are using an attribute selector here with a unique attribute to minimize the scope of the style to the host only. because we want to override the style only for that progress-bar on which we have applied our directive.
您可以像这样在模板中使用此指令.
you can use this directive in your template like this.
<mat-progress-bar [appProgressBarColor]="'orange'"
mode="determinate"
value="40"></mat-progress-bar>
我希望这会有所帮助.
这篇关于从代码更改角度材料进度条颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!