2016-08-26 5 views
10

다른 요소를 클릭 할 때 집중하기 위해 기본 요소에 액세스하려고합니다 (for "html"속성과 매우 유사합니다). for는 사용할 수 없습니다. . 이러한 유형의 요소에@viewChild가 작동하지 않습니다 - 정의되지 않은 nativeElement 속성을 읽을 수 없습니다.

그러나 나는 오류 얻을 :.

TypeError: Cannot read property 'nativeElement' of undefined

내가 그것을로드 그래서 ngAfterViewInit()에 nativeElement을 CONSOLE.LOG하려고하지만 여전히 오류가 발생을

I을 또한 클릭 이벤트 핸들러에서 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 템플릿을 (아마 irrel evant) :

<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> 

답변

17

@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가 설정되어 있지전에이 호출됩니다.

+0

이전에 설정되지 않은 경우 어떻게 설정합니까? – Demodave

+0

'keywordsInput'을 의미하는 경우, 사용자가 직접 설정하지 않아도 Angulars 변경 감지로 설정됩니다. –

+1

감사합니다. 그것은 나를 위해 일했다. – knigalye

관련 문제