3

在组件模板中,我正在使用 ElementRef 选择一个 svg 元素。它工作正常,但是当我构建应用程序并打开它时 elementRef 为空。

    @Component({
      selector: 'app-svg',
      template: `<div id="root">
        <object [data]='trustedUrl' type="image/svg+xml" height="450" width="650" #dataSvg></object>
      </div>`,
      styleUrls: ['./svg.component.css'] 

    })
constructor(private sanitizer: DomSanitizer, private elRef: ElementRef) {    
 }

elementRef 目标

@ViewChild('dataSvg') dataSvg: ElementRef;

将其传递给 elementRef 变量

ngOnInit() {
    this.elementRef = this.elRef.nativeElement.querySelector('#dataSvg');  
     }

加载内容后,我选择 svg :

ngAfterContentInit() {
    const elementRef = this.elementRef;

    // when content is loaded...
    elementRef.addEventListener('load', function (event) {
      // ...retrieve svg element

elementRef.querySelector('svg')为空

当我运行“ npm run build ”并转到 dist/index.html 时,contentDocument > 为 null

在此处输入图像描述

4

6 回答 6

3

您使用@ViewChild('dataSvg') dataSvg: ElementRef;但在您的模板中您没有为dataSvg.

有两种方法可以做到这一点:1)按照Angular Docs的解释使用@Directive 2)使用模板参考#:在你的情况下: <object ... #dataSvg></object>

如果您已经使用 Directive,则未提及,但在您的模板代码中,您只有一个id=dataSvg

于 2018-11-20T15:48:51.443 回答
2

根据官方文档,您无法访问该@ViewChild元素,除非您在AfterView钩子(AfterViewInitAfterViewChecked)而不是那个钩子中进行操作OnInit


  • 您可以在此处找到@ViewChild一篇关于、和之间差异的好@ViewChildren文章。@ContentChild@ContentChildren
于 2018-11-20T15:26:36.613 回答
2

DOM 尚未完全内置在ngOnInit. 您需要等待子项(此处为模板)被创建。

而不是ngOnInit,将您的代码放入ngAfterViewInit.

更多关于组件生命周期中的钩子的信息可以在 Angular 文档中找到。

于 2018-11-20T15:22:55.640 回答
0

我找到了附加 SVG 元素的兼容性解决方案:

在我的 svg 组件中,我使用绑定 innerHTML 设置了 svg 的源,当我的输入发生更改时,我正在使用服务加载 svg,该服务以安全的方式返回 svg 数据:

在组件中绑定 SVG 的数据源:

 @Component({
  selector: 'app-svg',
  template: `<div id="root">
    <div [innerHTML]="svgSafe" type="image/svg+xml" height="450" width="650" #dataSvg></div>
  </div>`,
  styleUrls: ['./svg.component.css'] ,
  animations: [

  ]
})

用输入加载 svg 的源代码:

 ngOninit() {

    var url = this.data.url;


    var id = 1; 

    if(url === 'assets/object_move.svg') {
       id = 1;
    }

    if(url === 'assets/object_wait.svg') {
      id = 2;
    }


    ..
    var dataSVG;
            this
              .loaderService
              .getSVGData(id)
              .subscribe((dataSvg) => {

      this.svgSafe = this.sanitizer.bypassSecurityTrustHtml(dataSvg.data);

            });
    }
于 2018-11-28T09:42:09.650 回答
0

存在与 ElementRef 相关的安全风险:

允许直接访问 DOM 会使您的应用程序更容易受到 XSS 攻击。

https://angular.io/api/core/ElementRef#description

考虑使用 Renderer2:

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

于 2020-06-25T14:46:35.337 回答
0

在下面的地方,明确给出读取:ElementRef,

@ViewChild('dataSvg') dataSvg: ElementRef;

它应该是

@ViewChild('dataSvg', { read: ElementRef }) dataSvg: ElementRef;

于 2019-12-06T06:39:29.347 回答