@viewChild가 작동하지 않음 - property nativeElement of undefined를 읽을 수 없습니다.
다른 요소를 클릭할 때 이 요소에 초점을 맞추기 위해 네이티브 요소에 액세스하려고 합니다(html 속성 "for"와 마찬가지로 -for는 이 유형의 요소에 사용할 수 없습니다).
그러나 오류가 발생합니다.
TypeError: 정의되지 않은 'nativeElement' 속성을 읽을 수 없습니다.
console.log를 nativeElement in으로 시도합니다.ngAfterViewInit()로드되지만 여전히 오류가 발생하도록 합니다.
또한 클릭 이벤트 핸들러에서 nativeElement에 액세스하여 다른 요소를 클릭할 때 요소에 초점을 맞출 수 있습니다. 뷰가 로드되기 전에 컴파일되기 때문에 이것이 이 요소를 망치는 것일까요?
예:
ngAfterViewInit() {
console.log(this.keywordsInput.nativeElement); // throws an error
}
focusKeywordsInput(){
this.keywordsInput.nativeElement.focus();
}
전체 코드:
사용 중인 HTML 템플릿의 관련 부분:
<div id="keywords-button" class="form-group" (click)="focusKeywordsInput()">
<input formControlName="keywords" id="keywords-input" placeholder="KEYWORDS (optional)"/>
<div class="form-control-icon" id="keywords-icon"></div>
</div>
component.ts:
import { Component, OnInit, AfterViewInit, ViewChild, ElementRef } from '@angular/core';
import { REACTIVE_FORM_DIRECTIVES,
FormGroup,
FormBuilder,
Validators,
ControlValueAccessor
} from '@angular/forms';
import { NumberPickerComponent } from './number-picker.component';
import { DistanceUnitsComponent } from './distance-units.component';
import { MapDemoComponent } from '../shared/map-demo.component';
import { AreaComponent } from './area-picker.component';
import { GoComponent } from './go.component';
import { HighlightDirective } from '../highlight.directive';
@Component({
selector: 'find-form',
templateUrl: 'app/find-page/find-form.component.html',
styleUrls: ['app/find-page/find-form.component.css'],
directives: [REACTIVE_FORM_DIRECTIVES,
NumberPickerComponent,
DistanceUnitsComponent,
MapDemoComponent,
AreaComponent,
GoComponent]
})
export class FindFormComponent implements OnInit, AfterViewInit {
findForm: FormGroup;
submitted: boolean; // keep track on whether form is submitted
events: any[] = []; // use later to display form changes
@ViewChild('keywords-input') keywordsInput;
//comment
constructor(private formBuilder: FormBuilder, el: ElementRef) {}
ngOnInit() {
this.findForm = this.formBuilder.group({
firstname: ['', [ Validators.required, Validators.minLength(5) ] ],
lastname: ['', Validators.required],
keywords: [],
area: ['', Validators.required],
address: this.formBuilder.group({
street: [],
zip: [],
city: []
})
});
this.findForm.valueChanges.subscribe(data => console.log('form changes', data));
}
ngAfterViewInit() {
console.log(this.keywordsInput.nativeElement); // throws an error
}
focusKeywordsInput(){
this.keywordsInput.nativeElement.focus();
}
save(isValid: boolean) {
this.submitted = true;
// check if model is valid
// if valid, call API to save customer
console.log(isValid);
}
}
전체 html 템플릿(관련 없는 probably)
<form class="text-uppercase" [formGroup]="findForm" (ngSubmit)="save(findForm.value, findForm.valid)">
<div class="row is-heading">
<div class="col-sm-8 offset-sm-2 col-md-6 offset-md-3 col-lg-4 offset-lg-4 input-group">
<h2 class="search-filter-heading heading m-x-auto">find vegan</h2>
</div>
</div>
<div class="row has-error-text">
<div class="col-sm-8 offset-sm-2 col-md-6 offset-md-3 col-lg-4 offset-lg-4 input-group btn-group" style="height:64px;">
<div style="position: relative; display: inline-block; width: 100%;">
<multiselect #multiselect></multiselect>
</div>
</div>
</div>
<div class="row error-text" [style.display]="multiselect.selectedCategories.length < 1 && submitted ? 'block' : 'none'">
<div class="col-sm-8 offset-sm-2 col-md-6 offset-md-3 col-lg-4 offset-lg-4 form-group input-group btn-group">
<small>Please select at least 1 category.</small>
</div>
</div>
<div class="row is-heading">
<div class="col-sm-8 offset-sm-2 col-md-6 offset-md-3 col-lg-4 offset-lg-4 input-group">
<h2 class="search-filter-heading heading m-x-auto">within</h2>
</div>
</div>
<div class="row">
<div class="col-sm-8 offset-sm-2 col-md-6 offset-md-3 col-lg-4 offset-lg-4 input-group btn-group" style="height:64px;">
<div style="position: relative; display: inline-block;">
<number-picker #numberPicker></number-picker>
</div>
<distance-units></distance-units>
</div>
</div>
<div class="row is-heading">
<div class="col-sm-8 offset-sm-2 col-md-6 offset-md-3 col-lg-4 offset-lg-4 input-group">
<h2 class="search-filter-heading heading m-x-auto">of</h2>
</div>
</div>
<div class="row has-error-text">
<div class="col-sm-8 offset-sm-2 col-md-6 offset-md-3 col-lg-4 offset-lg-4 input-group btn-group" style="height:64px;">
<div style="position: relative; display: inline-block; width: 100%;">
<my-area></my-area>
</div>
</div>
</div>
<div class="row error-text" [style.display]="multiselect.selectedCategories.length < 1 && submitted ? 'block' : 'none'">
<div class="col-sm-8 offset-sm-2 col-md-6 offset-md-3 col-lg-4 offset-lg-4 form-group input-group btn-group">
<small [hidden]="findForm.controls.firstname.valid || (findForm.controls.firstname.pristine && !submitted)">Please enter an area.</small>
</div>
</div>
<div class="row is-heading">
<div class="col-sm-8 offset-sm-2 col-md-6 offset-md-3 col-lg-4 offset-lg-4 input-group">
<h2 class="search-filter-heading heading m-x-auto">keywords</h2>
</div>
</div>
<div class="row form-group">
<div class="col-sm-8 offset-sm-2 col-md-6 offset-md-3 col-lg-4 offset-lg-4 input-group btn-group" style="height:64px;">
<div style="position: relative; display: inline-block; width: 100%;">
<div id="keywords-button" class="form-group" (click)="focusKeywordsInput()">
<input formControlName="keywords" id="keywords-input" placeholder="KEYWORDS (optional)"/>
<div class="form-control-icon" id="keywords-icon"></div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-8 offset-sm-2 col-md-6 offset-md-3 col-lg-4 offset-lg-4 input-group btn-group" style="height:64px;">
<div style="position: relative; display: inline-block; width: 100%;">
<go></go>
</div>
</div>
</div>
</form>
@ViewChild('keywords-input') keywordsInput;일치하지 않음id="keywords-input"
id="keywords-input"
대신 템플릿 변수가 되어야 합니다.
#keywordsInput
다음과 같이 낙타 케이스를 사용해야 합니다.-템플릿 참조 이름에는 사용할 수 없습니다.
@ViewChild()에서는 템플릿 변수의 이름을 문자열로 지원합니다.
@ViewChild('keywordsInput') keywordsInput;
또는 구성요소 또는 지시 유형:
@ViewChild(MyKeywordsInputComponent) keywordsInput;
https://stackoverflow.com/a/35209681/217408 도 참조
힌트:
keywordsInput이전에 설정되지 않음ngAfterViewInit()라고 합니다.
대상 요소가 숨겨진 요소 안에 있는 경우에도 이 오류가 발생합니다.HTML인 경우:
<div *ngIf="false">
<span #sp>Hello World</span>
</div>
당신의.@ViewChild('sp') sp정의되지 않습니다.
해결책
그런 경우에는 사용하지 마십시오.*ngIf.
대신 클래스를 사용하여 요소가 숨겨져 있는 것을 표시/숨깁니다.
<div [class.show]="shouldShow">...</div>
승인된 답변은 모든 면에서 맞으며 앱 구성 요소 중 하나에서 Google Map 렌더를 가져올 수 없는 경우 이 스레드를 우연히 발견했습니다.
이제 각 7+ 이상의 최근 각 버전을 사용하는 경우 다음 ViewChild 선언을 처리해야 합니다.
@ViewChild(selector: string | Function | Type<any>, opts: {
read?: any;
static: boolean;
})
자, 흥미로운 부분은 정의에 따라 말하는 정적 값입니다.
- static - 변경 탐지를 실행하기 전에 쿼리 결과를 확인하려면 True입니다.
이제 지도를 렌더링하기 위해 다음을 사용했습니다.
@ViewChild('map', { static: true }) mapElement: any;
map: google.maps.Map;
저도 비슷한 문제가 있었지만, 제 경우에는 그 문제를 읽으려고 했습니다.nativeElement내부에ngOnInit방법:
@ViewChild('userNameInput') userNameInput: ElementRef<HTMLInputElement>;
...
ngOnInit(): void {
this.userNameInput.nativeElement.focus();
}
로 변경했습니다.ngAfterViewInit그리고 모든게 잘 작동했습니다.
@ViewChild('userNameInput') userNameInput: ElementRef<HTMLInputElement>;
...
ngAfterViewInit(): void {
this.userNameInput.nativeElement.focus();
}
이 오류는 조건으로 래핑된 요소를 대상으로 지정하려고 할 때 발생합니다.
따라서 [hidden] 대신 ngIf를 사용하면 TypeError: 정의되지 않은 'nativeElement' 속성을 읽을 수 없습니다.
[숨김], 클래스를 사용합니다.쇼든 클래스든*ngif 대신 숨습니다.
<button (click)="displayMap()" class="btn btn-primary">Display Map</button>
<div [hidden]="!display">
<div #mapContainer id="map">Content to render when condition is true.</div>
</div>
조건()으로 때 이할 수 <div *ngIf="canShow"> <p #target>Targeted Element</p></div>
canShow렌더링 시 false이며, Angular는 렌더링되지 않기 때문에 해당 요소를 가져올 수 없습니다. 따라서 오류가 나타납니다.
중 는 는 A 를 입니다.display: hidden 대신 *ngIf따라서 요소는 렌더링되지만 조건이 충족될 때까지 숨겨집니다.
Github에서 자세히 보기
제 경우에는 그냥 확인만 하고 있습니다.
` @ViewChild('myinput') myInputField: ElementRef;
ngAfterViewInit() {
if (this.myInputField !== undefined) {
this.myInputField.nativeElement.focus();
}
}
DOM이 로드되기 전에 이러한 요소를 호출하면 이러한 오류가 나타납니다.항상 사용:
window.onload = function(){
this.keywordsInput.nativeElement.focus();
}
*ngif 제거
제 경우 @ViewChild 요소 안에서 저는 *ngIf를 아래와 같이 사용하고 있었습니다.
<ul class="menu" *ngIf="isMenuOpen" #menu>
<li *ngFor="let data of dropdownData" (click)="onClickOfVal(data)">
{{ data }}
</li>
</ul>
업데이트된 코드
<ul class="menu" [style.display]="isMenuOpen ? 'block' : 'none'" #menu>
<li *ngFor="let data of dropdownData" (click)="onClickOfVal(data)">
{{ data }}
</li>
</ul>
아래와 같이 캔버스를 초기화하는 것은 TypeScript/Angular 솔루션에 적합합니다.
const canvas = <HTMLCanvasElement> document.getElementById("htmlElemId");
const context = canvas.getContext("2d");
단순합니다 : 이 디렉토리를 가져옵니다.
import {Component, Directive, Input, ViewChild} from '@angular/core';
언급URL : https://stackoverflow.com/questions/39158922/viewchild-not-working-cannot-read-property-nativeelement-of-undefined
'programing' 카테고리의 다른 글
| gcc는 왜 오랫동안 경고를 가지고 있습니까? (0) | 2023.10.14 |
|---|---|
| 오디오 스트림이 주어지면 도어가 언제 쾅쾅 닫히는지 확인합니다(음압 레벨 계산?). (0) | 2023.10.14 |
| Eslint angular and jasmine: 정의되지 않음 - undefect (0) | 2023.10.14 |
| Gravity Forms 계산에서 지수 사용 (0) | 2023.10.14 |
| Oracle SQL Developer: 리플렉터에서 결과를 보는 방법은 무엇입니까? (0) | 2023.10.14 |