Angular SVG разные экземпляры, разделяющие одни и те же определения - PullRequest
1 голос
/ 13 июня 2019

У меня есть угловой компонент, где я изменяю заполнение статуса батареи svg, используя def.

    <svg #batteryIcon width="95%" height="95%" viewBox="0 0 260 399">
    <defs>
        <linearGradient #batteryLG id="batteryLG" x1="0.5" y1="1" x2="0.5" y2="0">
            <stop offset="0%" stop-opacity="1" stop-color="royalblue" />
            <stop [attr.offset]="value" stop-opacity="1" stop-color="royalblue" />
            <stop [attr.offset]="value" stop-opacity="0" stop-color="royalblue" />
            <stop offset="100%" stop-opacity="0" stop-color="royalblue" />
        </linearGradient>

    </defs>
<svg:rect id="rect" fill="url(#batteryLG)" x="-30" y="0" width=25% height="100%" ></svg:rect>
   </svg>

Это прекрасно работает, если у меня есть один экземпляр компонента. Если у меня есть несколько компонентов, которые имеют разные значения для «значения», все компоненты показывают заполнение первого компонента.

Не уверен, где я допустил ошибку

Аналогичная проблема: Динамическое обновление смещений

PS: у меня на самом деле длинный путь к значку батареи .. Как-то Stackoverflow не принимает длинный путь. Вот почему я заменил путь на прямоугольник. Если бы это был прямоугольник, я мог бы изменить его высоту, чтобы добиться того, что мне нужно :)

1 Ответ

2 голосов
/ 13 июня 2019

Проблема в том, что все элементы linearGradient имеют одинаковый id, а именно batteryLG.Вы можете сделать каждый id уникальным, позволяя каждой фигуре ссылаться на свой градиент.Один из способов добиться этого - определить счетчик static в классе компонента, увеличить его для каждого экземпляра и включить его значение в свойство batteryLinearGradientId компонента:

export class MySvgComponent {
  @Input() value: number;
  private static counter = 0;
  batteryLinearGradientId = "batteryLinearGradient_" + MySvgComponent.counter++;
}

Затем можносвяжите это свойство с id в шаблоне и обратитесь к нему по URL-адресу атрибута rect fill:

<svg #batteryIcon width="95%" height="95%" viewBox="0 0 260 399">
    <defs>
        <linearGradient [id]="batteryLinearGradientId" x1="0.5" y1="1" x2="0.5" y2="0">
            <stop offset="0%" stop-color="royalblue" />
            <stop [attr.offset]="value + '%'" stop-color="royalblue" />
            <stop [attr.offset]="value + '%'" stop-color="yellow" />
            <stop offset="100%" stop-color="yellow" />
        </linearGradient>
    </defs>
    <svg:rect [attr.fill]="'url(#' + batteryLinearGradientId + ')'" x="-30" y="0" width=25% height="100%"></svg:rect>
</svg>

См. this stackblitz для демонстрации.Обратите внимание, что я изменил определение градиентных упоров, чтобы упростить демонстрацию.

...