#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 })
в этом случае она будет доступна в ngOnInit2. @MikeJerred Спасибо за дополнение! это правильно. Также стоит отметить, что это доступно только в версии 9 и выше. И это
ngOnChanges
выполняется первым перед ngOnInit, так что это все еще может быть проблемой в случае OP.