我将一个svg加载为对象:
<object data="assets/img/states.svg" type="image/svg+xml" id="map"></object>
此svg包含一个大的png映射以及几个rect和text元素。
<rect
y="224.72084"
x="644.87109"
height="231.68137"
width="101.08391"
id="RECT_TO_GET" />
我想像使用普通的html元素一样将所有rect
元素放在数组中:
@ViewChildren('rect') rects !: QueryList<any>;
this.rects.forEach(r=> {
console.log(r);
});
问题在于rects数组始终为空。我试图将它们放入ngViewAfterInit()
和ngAfterViewChecked()
中都没有成功。如何达到svg的元素?
我还没有尝试过getElementsById()
来获得它们,如果可能的话,我想以有角度的方式来做。
整个过程就是在获得每个rect元素后为其提供上下文颜色。
答案 0 :(得分:2)
ViewChild
或ViewChildren
不支持CSS选择器
https://angular.io/api/core/ViewChild
受支持的选择器包括:
- 具有@Component或@Directive装饰器的任何类
- 模板引用变量作为字符串(例如,使用@ViewChild('cmp')`查询)
- 在当前组件的子组件树中定义的任何提供程序(例如@ViewChild(SomeService)someService:SomeService)
- 通过字符串令牌定义的任何提供程序(例如@ViewChild('someToken')someTokenVal:任意)
- TemplateRef(例如,使用@ViewChild(TemplateRef)模板进行查询;)
您可以从模板引用变量中获取HtmlElement,并在加载对象元素资源后开始尝试对其进行操作
html
<object #mySvg data="./assets/new.svg" type="image/svg+xml" id="map"></object>
组件
@ViewChild('mySvg') mySvg;
ngOnInit() {
const objElm = (this.mySvg.nativeElement as HTMLObjectElement);
objElm.onload = () => {
const paths = objElm.contentDocument.querySelectorAll('path');
paths.forEach((path,index) => {
console.log(`path:${index} , d=${path.getAttribute("d")}`);
})
}
}
答案 1 :(得分:0)
进行了更多研究,找到了以下解决方案。有趣的是,此代码位于我的角度组件的ngAfterViewInit方法中,它仍然需要window.onload事件侦听器正常工作。为什么?
window.addEventListener("load", function() {
var svgObject = document.getElementById('map').contentDocument;
var svg = svgObject.getElementById('svg48152');
console.log(svg);
const rects = svg.querySelectorAll('rect');
console.log(rects);
rects.forEach(r => {
console.log(r);
});
});
关键组件是contentDocument
属性和onload
事件侦听器。一些有用的信息以备将来参考:Using Javascript with SVG