簡體   English   中英

如何通過 Angular ViewChildren 訪問 SVG 元素

[英]How to reach SVG elements by Angular ViewChildren

我有一個 svg 作為對象加載:

<object data="assets/img/states.svg" type="image/svg+xml" id="map"></object>

這個 svg 包含一個大的 png 地圖和幾個矩形和文本元素。

<rect
     y="224.72084"
     x="644.87109"
     height="231.68137"
     width="101.08391"
     id="RECT_TO_GET" />

我想獲取數組中的所有rect元素,就像我處理普通 html 元素一樣:

@ViewChildren('rect') rects !: QueryList<any>;
this.rects.forEach(r=> {
            console.log(r);
        });

問題是 rects 數組始終為空。 我試圖在ngViewAfterInit()ngAfterViewChecked()獲取它們但沒有成功。 我怎樣才能到達 svg 的元素?

我還沒有嘗試通過getElementsById()獲取它們,如果可能的話,我想以有角度的方式進行。

整個過程就是在我得到每個 rect 元素后給出它們的上下文顏色。

ViewChildViewChildren不支持 CSS 選擇器

https://angular.io/api/core/ViewChild

支持的選擇器包括:

  • 任何帶有 @Component 或 @Directive 裝飾器的類
  • 作為字符串的模板引用變量(例如使用@ViewChild('cmp')` 查詢)
  • 當前組件的子組件樹中定義的任何提供者(例如@ViewChild(SomeService) someService: SomeService)
  • 通過字符串標記定義的任何提供者(例如@ViewChild('someToken') someTokenVal: any)
  • 一個 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")}`);
        })

    }    
  }

做了一些更多的研究,找到了下面的解決方案。 有趣的是,這段代碼在我的 angular 組件的 ngAfterViewInit 方法中,它仍然需要 window.onload eventlistener 才能工作。 為什么?

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

我只是想在@Chunbin Li 給出的答案中添加一件小事(遺憾的是,我目前沒有足夠的聲譽發表評論)。 無論如何,在評論部分,@Perrier 說this.rects仍然是一個空的節點列表。 這可以通過使用不同的生命周期方法來解決。

使用ViewChild ,通常使用生命周期方法ngAfterViewInit() 在@Chunbin Li 的回答中,該函數是在ngOnInit()調用的,因此很可能 SVG 沒有足夠的時間進行渲染。 如果您在ngAfterViewInit()調用該函數,它將為 DOM 提供足夠的時間來完全呈現 SVG,並且可以訪問 SVG 的屬性。

如需進一步閱讀,請查看ViewChild上的 angular 文檔。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM