简体   繁体   English

在Angular中动态更新SVG

[英]Dynamically updating SVG in Angular

I am trying to programatically add paths to an SVG element in an HTML in an Angular application. 我试图以编程方式在Angular应用程序的HTML中将路径添加到SVG元素。 The problem is that the paths are being added to the DOM but are not rendering in the browser. 问题在于路径已添加到DOM,但未在浏览器中呈现。 Despite a day of searching and experimenting, I can't find what the issue is. 尽管经过了一整天的搜索和试验,我仍然找不到问题所在。 I've reproduced the problem in a small app. 我已经在一个小应用程序中重现了该问题。 Hopefully someone can spot what I'm doing wrong. 希望有人能发现我在做什么错。

Angular template for the component: 组件的角度模板:

<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>

And the Typescript: 和打字稿:

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)
  }
}

When you run the app, the hardcoded path in the template is displayed correctly. 当您运行应用程序时,模板中的硬编码路径会正确显示。 However when you click on the button, a path is inserted as child of the SVG element but the path isn't rendering in the browser. 但是,当您单击按钮时,路径将作为SVG元素的子级插入,但该路径不会在浏览器中呈现。

Angular keeps namespaces map in its code: 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/',
};

which is used to create element with namespace: 用于创建带有名称空间的元素

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

So try using svg key as namespace: 因此,请尝试使用svg键作为名称空间:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM