构建角度应用后,elementRef为空

时间:2018-11-20 15:20:39

标签: angular dom elementref

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

    @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>为空

enter image description here

6 个答案:

答案 0 :(得分:2)

根据 official Doc ,您无法访问@ViewChild元素,除非您在 AfterView 钩子中进行了此操作( AfterViewInitAfterViewChecked)代替OnInit


  • You can find here 不错的文章,介绍了@ViewChild@ViewChildren@ContentChild@ContentChildren之间的差异。

答案 1 :(得分:2)

您使用@ViewChild('dataSvg') dataSvg: ElementRef;,但在模板中尚未为dataSvg提供任何锚点。

有两种方法可以做到这一点: 1)按照Angular Docs中的说明使用@Directive 2)使用模板引用#<object ... #dataSvg></object>

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

答案 2 :(得分:1)

DOM尚未在ngOnInit中完全构建。您需要等待子级(此处为模板)的创建。

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

有关组件生命周期中的钩子的更多信息,请参见in the Angular documentation

答案 3 :(得分: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);

            });
    }

答案 4 :(得分:0)

在以下位置,显式给出以下内容:ElementRef,

@ViewChild('dataSvg')dataSvg:ElementRef;

应该是

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

答案 5 :(得分:0)

与ElementRef相关的安全风险:

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

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

考虑使用Renderer2:

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