Динамическое обновление SVG в Angular

Я пытаюсь программно добавить пути к элементу SVG в HTML в приложении Angular. Проблема в том, что пути добавляются в DOM, но не отображаются в браузере. Несмотря на день поиска и экспериментов, я не могу найти, в чем проблема. Я воспроизвел проблему в небольшом приложении. Надеюсь, кто-нибудь поймет, что я делаю не так.

Угловой шаблон для компонента:

<div style = "text-align:center">
  Click the button to add a path to the svg
  <button (click) = "onClickMe()">Click me!</button>
</div>
<div>
  <svg #svg
       xmlns = "http://www.w3.org/2000/svg"
       width = "200mm"
       height = "200mm"
       viewBox = "0 0 200 200">
    <path
      style = "fill:#000000;fill-opacity:1;stroke:#000000;"
      d = "M 60,147 h 40 v 30 H 85 V 157 H 75 v 20 H 60 Z"
      id = "path1">
    </path>
  </svg>
</div>

И Машинопись:

import {Component, ElementRef, Renderer2, ViewChild} from '@angular/core'

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  @ViewChild('svg') svg: ElementRef

  constructor(private renderer: Renderer2) {
  }

  onClickMe() {
    const path = this.renderer.createElement("path", 'http://www.w3.org/2000/svg')
    this.renderer.setAttribute(path, "d", 'M60,150 H50 V 50 Z')
    this.renderer.setAttribute(path, "style", "fill:#F00;")

    this.renderer.appendChild(this.svg.nativeElement, path)
  }
}

При запуске приложения жестко заданный путь в шаблоне отображается правильно. Однако, когда вы нажимаете кнопку, путь вставляется как дочерний элемент SVG, но путь не отображается в браузере.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
4
0
2 631
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Angular хранит карту пространств имен в своем коде:

export const NAMESPACE_URIS: {[ns: string]: string} = {
  'svg': 'http://www.w3.org/2000/svg',
  'xhtml': 'http://www.w3.org/1999/xhtml',
  'xlink': 'http://www.w3.org/1999/xlink',
  'xml': 'http://www.w3.org/XML/1998/namespace',
  'xmlns': 'http://www.w3.org/2000/xmlns/',
};

который используется для создать элемент с пространством имен:

if (namespace) {
   return document.createElementNS(NAMESPACE_URIS[namespace], name);
}

Поэтому попробуйте использовать ключ svg в качестве пространства имен:

const path = this.renderer.createElement("path", 'svg')
                                                  ^^^^

Фантастика - вот и все.

matt helliwell 11.11.2018 20:40

Другие вопросы по теме