Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 角度:动态渲染时SVG路径标记不可见_Javascript_Html_Css_Angular_Svg - Fatal编程技术网

Javascript 角度:动态渲染时SVG路径标记不可见

Javascript 角度:动态渲染时SVG路径标记不可见,javascript,html,css,angular,svg,Javascript,Html,Css,Angular,Svg,我有一个从服务器获取的SVG文件,然后我必须将其渲染到我拥有的视图中 问题是我不能使用或[innerHTML],因为我需要添加用户交互和事件,并将其集成到Angular的生命周期中 因此,我编写了以下代码来解析XML并将其呈现为组件模板中的具体元素: svg映射测试.component.ts: import{AfterViewChecked,AfterViewInit,ChangeDetectorRef,Component,Inject,OnInit}从'@angular/core'导入; 从'

我有一个从服务器获取的SVG文件,然后我必须将其渲染到我拥有的视图中

问题是我不能使用
[innerHTML]
,因为我需要添加用户交互和事件,并将其集成到Angular的生命周期中

因此,我编写了以下代码来解析XML并将其呈现为组件模板中的具体元素:

svg映射测试.component.ts:

import{AfterViewChecked,AfterViewInit,ChangeDetectorRef,Component,Inject,OnInit}从'@angular/core'导入;
从'@angular/common'导入{DOCUMENT};
常量svg=`
\t、 st0{fill:#F89464;}
\t、 st1{fill:#B6B773;}
\t、 st2{fill:#4CFEFC;}
\t、 st3{fill:#606060;}
\t、 st4{fill:#FFFFFF;}
\t
\t\t
\t\t\t
\t\t
\t
`
@组成部分({
选择器:“应用程序svg映射测试”,
templateUrl:'./svg映射测试.component.html',
样式URL:['./svg映射测试.component.scss']
})
导出类SvgMapTestComponent实现OnInit、AfterViewInit、AfterViewChecked{
xmlDom:文档;
构造函数(@Inject(DOCUMENT)私有文档:DOCUMENT,私有cdRef:ChangeDetectorRef){
}
ngOnInit():void{
const parser=new DOMParser();
this.xmlDom=parser.parseFromString(svg,'image/svg+xml');
}
伪数组(集合:HTMLCollection){
常数res=[];
for(设i=0;i
svg映射测试.component.html:


.st0{fill:#F89464;}
.st1{fill:#B6B773;}
.st2{fill:#4CFEFC;}
.st3{fill:#606060;}
.st4{fill:#FFFFFF;}
但是,没有显示任何内容。 现在,当我在浏览器中检查DOM时,它都在那里并且呈现正确,但我注意到,
d
属性没有反映在元素样式中,如以下示例所示:

我试图在
ngAfterViewInit
中使用
detectChanges
,但没有成功。 当我摆弄检查器并在SVG中手动添加一个随机的
时,一切突然变得可见,
d
属性正确地反映在相应元素的样式中


注意:如果您认为有更好的方法来实现我的目标,请告诉我。

显然,这是Angular中长期存在的错误

import { AfterViewChecked, AfterViewInit, ChangeDetectorRef, Component, Inject, OnInit } from '@angular/core';
import { DOCUMENT } from '@angular/common';

const svg = `
<!-- Generator: Adobe Illustrator 24.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1180.5 841.9" style="enable-background:new 0 0 1180.5 841.9;" xml:space="preserve">
<style type="text/css">
\t.st0{fill:#F89464;}
\t.st1{fill:#B6B773;}
\t.st2{fill:#4CFEFC;}
\t.st3{fill:#606060;}
\t.st4{fill:#FFFFFF;}
</style>
<g id="s:gold">
\t<g id="r:a">
\t\t<g id="c:a2">
\t\t\t<path class="st0" d="M911.9,62.3H896c-2.1,0-3.8-1.7-3.8-3.8V42.6c0-2.1,1.7-3.8,3.8-3.8h15.9c2.1,0,3.8,1.7,3.8,3.8v15.9
\t\t\t\tC915.7,60.6,914,62.3,911.9,62.3z"/>
\t\t</g>
\t</g>
</g>
</svg>
`


@Component({
  selector: 'app-svg-map-test',
  templateUrl: './svg-map-test.component.html',
  styleUrls: ['./svg-map-test.component.scss']
})
export class SvgMapTestComponent implements OnInit, AfterViewInit, AfterViewChecked {

  xmlDom: Document;

  constructor(@Inject(DOCUMENT) private document: Document, private cdRef: ChangeDetectorRef) {
  }

  ngOnInit(): void {
    const parser = new DOMParser();
    this.xmlDom = parser.parseFromString(svg, 'image/svg+xml');
  }

  fakeArray(collection: HTMLCollection) {
    const res = [];
    for (let i = 0; i < collection.length; i++) {
      res.push(collection.item(i));
    }
    return res;
  }

}

Edit:我发现您可以通过将ng模板中使用的SVG的每个子元素用自己的SVG标记包围起来来缓解这个问题。它没有明显的缺点。

import { AfterViewChecked, AfterViewInit, ChangeDetectorRef, Component, Inject, OnInit } from '@angular/core';
import { DOCUMENT } from '@angular/common';

const svg = `
<!-- Generator: Adobe Illustrator 24.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1180.5 841.9" style="enable-background:new 0 0 1180.5 841.9;" xml:space="preserve">
<style type="text/css">
\t.st0{fill:#F89464;}
\t.st1{fill:#B6B773;}
\t.st2{fill:#4CFEFC;}
\t.st3{fill:#606060;}
\t.st4{fill:#FFFFFF;}
</style>
<g id="s:gold">
\t<g id="r:a">
\t\t<g id="c:a2">
\t\t\t<path class="st0" d="M911.9,62.3H896c-2.1,0-3.8-1.7-3.8-3.8V42.6c0-2.1,1.7-3.8,3.8-3.8h15.9c2.1,0,3.8,1.7,3.8,3.8v15.9
\t\t\t\tC915.7,60.6,914,62.3,911.9,62.3z"/>
\t\t</g>
\t</g>
</g>
</svg>
`


@Component({
  selector: 'app-svg-map-test',
  templateUrl: './svg-map-test.component.html',
  styleUrls: ['./svg-map-test.component.scss']
})
export class SvgMapTestComponent implements OnInit, AfterViewInit, AfterViewChecked {

  xmlDom: Document;

  constructor(@Inject(DOCUMENT) private document: Document, private cdRef: ChangeDetectorRef) {
  }

  ngOnInit(): void {
    const parser = new DOMParser();
    this.xmlDom = parser.parseFromString(svg, 'image/svg+xml');
  }

  fakeArray(collection: HTMLCollection) {
    const res = [];
    for (let i = 0; i < collection.length; i++) {
      res.push(collection.item(i));
    }
    return res;
  }

}


<ng-template #rectElement let-rect>
  <svg>
    <rect [attr.x]="rect.getAttribute('x')"
          [attr.y]="rect.getAttribute('y')"
          [class]="rect.className"
          [attr.width]="rect.getAttribute('width')"
          [attr.height]="rect.getAttribute('height')"></rect>
  </svg>
</ng-template>