Как избежать TypeError в angular?

#angular #typescript #viewchild

#angular #typescript #viewchild

Вопрос:

В файле .ts у меня есть :-

     @Component({
      selector: 'stl-app',
      templateUrl: './stl-app.component.html',
      styleUrls: ['./stl-app.component.scss']
    })
    export class ImlStlAppComponent implements OnChanges {
    
      @Input()
      filename: string;
      @Input()
      colorname: any;
      @Input()
      perspective: number;
    
      private scene: Scene;
      private camera: PerspectiveCamera;
      private renderer: WebGLRenderer;
      @ViewChild("myCanvas") myCanvas: any;
    
      constructor(private render: Renderer2,private sanitizer: DomSanitizer) {
      }
    
      ngOnInit(): void {
        //add listener for the resize of the window - will resize the renderer to fit the window
        let global = this.render.listen('window', 'resize', (evt) => {
          this.onWindowResize();
        })
      }
    
      ngOnChanges(changes: SimpleChanges) {
        this.mySubmit();
      }
    
      mySubmit() {
       
        //renderer
        this.renderer = new WebGLRenderer({ alpha: true, canvas: this.myCanvas.nativeElement});
        this.renderer.setSize(this.width, this.height);
    
       //Set scene, camera,lights etc
    
        })
    
        //request animation
        this.animate(this.controls);
    
      }
    
//will resize the renderer and the camera to the right size of the window

      onWindowResize() {
    }
    }
  

В HTML-файле у меня есть :-

     <div style="text-align:center">
          <canvas #myCanvas id="myCanvas">
          </canvas>
        </div>
  

* Ошибка в консоли следующая: — «ОШИБКА core.js: 4197 ОШИБКА ТИПА: не удается прочитать свойство ‘nativeElement’ неопределенного значения в StlAppComponent.mySubmit (stl-app.component.ts:59) и в StlAppComponent.ngOnChanges (stl-app.component.ts:51)».

Как избежать этой проблемы с ‘nativeElement’? и в чем причина этой ошибки?*

Ответ №1:

Перехват жизненного цикла Angular ngOnChanges выполняется первым перед визуализацией шаблона компонента, что означает, что ваш @ViewChild MyCanvas все еще не инициализирован Angular, он будет иметь значение только после инициализации представления.

Вот документация о порядке следования крючков жизненного цикла компонентов Angular :https://angular.io/guide/lifecycle-hooks#lifecycle-event-sequence

Быстрым решением было бы окружить вызов submit() проверкой значения, подобной этой

       ngOnChanges(changes: SimpleChanges) {
        if(this.myCanvas) {
          this.mySubmit();
        }
      }
  

И вы можете использовать ngAfterViewInit() перехват, если хотите, чтобы что-то выполнялось сразу после инициализации вашего представления (и вы получаете значение в своем myCanvas )

Комментарии:

1. В качестве альтернативы, если дочерний элемент view не добавлен или удален со страницы с помощью привязок (например, будучи потомком ngIf или ngFor), вы можете добавить статическую опцию, например: @ViewChild('myCanvas', { static: true }) в этом случае она будет доступна в ngOnInit

2. @MikeJerred Спасибо за дополнение! это правильно. Также стоит отметить, что это доступно только в версии 9 и выше. И это ngOnChanges выполняется первым перед ngOnInit, так что это все еще может быть проблемой в случае OP.