2016-08-26 20 views
10

Próbuję uzyskać dostęp do elementu natywnego, aby skupić się na nim po kliknięciu innego elementu (podobnie jak atrybut html "dla" - ponieważ nie można go użyć . na elementach tego typu@viewChild nie działa - nie można odczytać właściwości nativeElement z undefined

Jednakże pojawia się błąd.

TypeError: Cannot read property 'nativeElement' of undefined

próbuję console.log się nativeElement w ngAfterViewInit() tak, że jest załadowany, ale to wciąż zgłasza błąd

I również uzyskaj dostęp do nativeElement w procedurze obsługi zdarzeń kliknięcia, dzięki czemu mogę skupić się na elemencie po kliknięciu innego elementu - czy to jest prawdopodobnie to, co je fałszuje, ponieważ kompiluje się przed załadowaniem widoku ?.

np

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

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

pełny kod:

odpowiednia część szablonu html używany:

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

pełny szablon HTML (prawdopodobnie 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> 

Odpowiedz

17

@ViewChild('keywords-input') keywordsInput; nie pasuje id="keywords-input"

id="keywords-input" 

powinno być zamiast zmienna szablonu:

#keywordsInput 

Zauważ, że sprawa wielbłąd powinien być stosowany, ponieważ jest - niedozwolone w nazwach referencyjnych szablonów.

@ViewChild() obsługuje nazw zmiennych szablonu jako wyrażenie:

@ViewChild('keywordsInput') keywordsInput; 

lub elementów lub dyrektywa typy:

@ViewChild(MyKeywordsInputComponent) keywordsInput; 

Zobacz również https://stackoverflow.com/a/35209681/217408

Podpowiedź:
keywordsInput nie jest ustawiony przed ngAfterViewInit() jest nazywane

+0

Jeśli nie jest ustawione wcześniej, jak to ustawić po? – Demodave

+0

Jeśli masz na myśli 'keywordsInput', to nie ustawiasz go samodzielnie, jest on ustawiony przez wykrywanie zmian Angulars. –

+1

dziękuję. to zadziałało dla mnie. – knigalye

Powiązane problemy