Изменить цвет индикатора выполнения углового материала из кода - PullRequest
0 голосов
/ 14 сентября 2018

Мне нужно динамически изменить цвет индикатор выполнения углового материала . Я понял, что это не так просто, так как лучше это сделать?

Требования:

  1. Я получу цветной шестнадцатеричный код от внешнего API. Поэтому я не могу создать набор предопределенных тем
  2. Цвет фона будет белым. Поэтому мне нужен только один цвет, а не вся палитра (светлее, темнее).

ссылка по теме: (1)

Ответы [ 4 ]

0 голосов
/ 06 июля 2019

Мы можем создать директиву атрибута, которая принимает значение цвета и переопределяет стили по умолчанию <mat-progress-bar> для нас.

вот рабочая демонстрация: https://stackblitz.com/edit/material-progress-bar-color-directive

вот краткоеобъяснение:

Если мы проверяем <mat-progress-bar> в инструментах разработчика.мы обнаружим, что цвет индикатора выполнения определяется в псевдоэлементе ::after следующим образом.

.mat-progress-bar-fill::after {
    background-color: #3f51b5;
}

И, как мы уже знаем, невозможно напрямую манипулировать псевдоэлемент с использованием метода DOM querySelector ().Но мы можем добавить новые стили, которые также могут иметь правила для псевдоэлементов.Проверьте эту тему для более подробной информации.https://stackoverflow.com/a/21709814/1160236

Итак, мы можем составить директиву, которая позаботится о добавлении для нас новых стилей.

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 и добавление его только внутри элемента host.

А внутри метода updateColor() мы обновляем innerText тега стиля, который мы добавили.обратите внимание, что мы используем здесь селектор атрибута с уникальным атрибутом, чтобы минимизировать область применения стиля только для хоста.потому что мы хотим переопределить стиль только для того индикатора выполнения, к которому мы применили нашу директиву.

вы можете использовать эту директиву в своем шаблоне следующим образом.

<mat-progress-bar [appProgressBarColor]="'orange'"
                  mode="determinate" 
                  value="40"></mat-progress-bar>

Я надеюсь, что этопоможет.

0 голосов
/ 07 октября 2018

Обновление:

Избегайте использования глубоких, TL; DR : Глубина технически недействительна (например, глубокая оценка: p)

Для получения дополнительной информации см .: Использование / Deep / и >>> в Angular 2

Теперь, чтобы изменить цвет индикатора хода выполнения мата,

Перейдите к вашему файлу styles.scss (или к главному файлу css / scss в вашем проекте)

Добавить этот класс ->

.green-progress .mat-progress-bar-fill::after {
    background-color: green !important;
}

Ваш мат-прогресс должен использовать вышеуказанный класс, например ->

<mat-progress-bar class="green-progress" mode="indeterminate"></mat-progress-bar>
0 голосов
/ 26 февраля 2019

Я столкнулся с этой проблемой, и ни одно из предложенных решений на самом деле не решило проблему так, как я ее понял.Поработав, хотя и по-другому, обдумав это, я считаю, что нашел управляемое решение для динамического изменения цветов mat-progress-bar, когда они неизвестны перед вызовом API (или пользовательским вводом).Я создал пример для stackblitz для игры, но в конечном итоге он работает так:

  1. При инициализации создайте style HTMLElement, к которому вы можете обратиться позже.
  2. На любом желаемом триггере (в данном примере это изменение входного значения) очистите элемент style, переназначьте цвета для пользовательского css и снова присоедините к head
// in app.component.ts

  styleElement: HTMLStyleElement;
  colors : Array<string> = ["#ff00ff", "#00ff00"];

changeColors() {
  const head = document.getElementsByTagName('head')[0];
  const css = `
  .style1 .mat-progress-bar-fill::after {
    background-color: ${this.colors[0]} !important;
  }

  .style2 .mat-progress-bar-fill::after {
    background-color: ${this.colors[1]} !important;
  }
  `;
  this.styleElement.innerHTML = '';
  this.styleElement.type = 'text/css';
  this.styleElement.appendChild(document.createTextNode(css));
  head.appendChild(this.styleElement);

}

ngOnInit() {
  this.styleElement = document.createElement('style');
  this.changeColors();
}
<!-- In app.component.html -->
<p>
  <mat-progress-bar mode="determinate" value=70 class="style1"></mat-progress-bar>
</p><p>
  <mat-progress-bar mode="determinate" value=40 class="style2"></mat-progress-bar>
</p>
<div><mat-form-field><input matInput type="color" placeholder="Style 1" [(ngModel)]="colors[0]" (change)="changeColors()" /></mat-form-field>
<mat-form-field><input matInput type="color" placeholder="Style 2" [(ngModel)]="colors[1]" (change)="changeColors()" /></mat-form-field></div>
0 голосов
/ 15 сентября 2018

мат-прогресс-бар

/deep/ .mat-progress-bar-fill::after {
    background-color: green;
}

/deep/ .mat-progress-bar-buffer {
    background: #E4E8EB;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...