2016-08-26 15 views
10

Başka bir öğe tıklatıldığında ("html özniteliği" gibi) odaklanmak için yerel bir öğeye erişmeye çalışıyorum - kullanılamadığı için . Bu tip unsurları@viewChild çalışmıyor - property native özelliği bulunamıyor undefined

ancak hatayı alıyorum:.

TypeError: Cannot read property 'nativeElement' of undefined

Ben yüklenir böylece ngAfterViewInit() yılında nativeElement console.log çalışıyorum ama yine de hata atar

I Ayrıca click olay işleyicisinde nativeElement öğesine erişin, böylece başka bir öğe tıklandığında öğeye odaklanabileceğim - bu muhtemelen görüntüyü yüklemeden önce derlediğinden, onu mucking yapan şey olabilir mi?

örn:

 ngAfterViewInit() { 
    console.log(this.keywordsInput.nativeElement); // throws an error 
    } 

    focusKeywordsInput(){ 
     this.keywordsInput.nativeElement.focus(); 
    } 

tam Kod:

kullanılan html şablonu

ilgili kısmı:

 <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); 
    } 
} 

tam html şablonu (muhtemelen 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> 

cevap

17

@ViewChild('keywords-input') keywordsInput; eşleşmeyen id="keywords-input"

id="keywords-input" 

yerine şablon değişkeni olmalıdır: - olduğundan, deve durumda kullanılması gerektiğini

#keywordsInput 

Not şablon referans adlarına izin verilmiyor.

@ViewChild() dize olarak şablon değişkenlerinin isimleri destekler:

@ViewChild('keywordsInput') keywordsInput; 

veya bileşen veya direktif türleri:

@ViewChild(MyKeywordsInputComponent) keywordsInput; 

Ayrıca bkz https://stackoverflow.com/a/35209681/217408

İpucu:
keywordsInput ayarlanmamış 0123'ten önce,

+0

olarak adlandırılır. Daha önceden ayarlanmadıysa, bunu nasıl ayarladınız? – Demodave

+0

Eğer 'keywordsInput' kastediyorsanız, bunu kendiniz ayarlamazsınız, Angulars değişim algılaması ile ayarlanır. –

+1

Teşekkürler. benim için çalıştı. – knigalye