Javascript 角度:动态渲染时SVG路径标记不可见
我有一个从服务器获取的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'导入; 从'
或[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>