elementRef является нулевым после построения углового приложения

В шаблоне компонента я выбираю элемент svg с ElementRef. Он работает нормально, но когда я собираю приложение и открываю его, 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 > имеет значение null:

введите описание изображения здесь

4 ответа

Ты используешь @ViewChild('dataSvg') dataSvg: ElementRef; но в вашем шаблоне вы не указали привязку для dataSvg,

Есть 2 способа сделать это: 1) использование @Directive, как описано в Angular Docs2) использование ссылки на шаблон #:в твоем случае:<object ... #dataSvg></object>

Не упоминается, если вы уже используете Директиву, но в коде шаблона у вас есть только id=dataSvg

Согласно официальному документу, вы не можете получить доступ к @ViewChild элемент, если вы не делаете это в хуке AfterView (AfterViewInit или же AfterViewChecked) вместо OnInit один.


DOM еще не полностью встроен ngOnInit, Вам нужно подождать, пока дети (шаблон здесь) будут созданы.

Вместо ngOnInitвставьте свой код в ngAfterViewInit,

Более подробную информацию о хуках в жизненном цикле компонентов можно найти в документации Angular.

В приведенном ниже месте явно дайте читать: ElementRef,

@ViewChild('dataSvg') dataSvg: ElementRef;

Должен быть

@ViewChild('dataSvg', {читать: ElementRef }) dataSvg: ElementRef;

С ElementRef связана угроза безопасности:

Разрешение прямого доступа к DOM может сделать ваше приложение более уязвимым для XSS-атак.

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

Рассмотрите возможность использования Renderer2:

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

Я нашел свое решение совместимости для добавления элемента SVG:

в моем компоненте svg я устанавливаю источник svg с привязкой innerHTML, когда мой ввод изменяется, я загружаю 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);

            });
    }
Другие вопросы по тегам