2016-08-26 29 views
10

Tôi đang cố truy cập phần tử gốc để tập trung vào yếu tố đó khi phần tử khác được nhấp (giống như thuộc tính html "cho" - không thể sử dụng . trên các yếu tố thuộc loại này@viewChild không hoạt động - không thể đọc thuộc tính gốcĐiều khoản không xác định

Tuy nhiên tôi nhận được lỗi:.

TypeError: Cannot read property 'nativeElement' of undefined

tôi cố gắng console.log các nativeElement trong ngAfterViewInit() để nó được nạp nhưng nó vẫn ném lỗi

tôi cũng thế truy cập nativeElement trong trình xử lý sự kiện nhấp chuột, để tôi có thể tập trung phần tử khi một phần tử khác được nhấp vào - đây có thể là thứ đang nhổ nó không, vì nó biên dịch trước khi khung nhìn đã tải ?.

ví dụ:

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

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

Mã đầy đủ:

phần liên quan của mẫu html đang được sử dụng:

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

đầy đủ mẫu html (có lẽ là không liên quan 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> 

Trả lời

17

@ViewChild('keywords-input') keywordsInput; không phù hợp id="keywords-input"

id="keywords-input" 

nên thay vì một mẫu biến:

#keywordsInput 

Lưu ý rằng trường hợp lạc đà nên được sử dụng, vì - là không được phép trong tên tham chiếu mẫu.

@ViewChild() hỗ trợ tên của các biến mẫu như chuỗi:

@ViewChild('keywordsInput') keywordsInput; 

hoặc một thành phần hoặc chỉ thị loại:

@ViewChild(MyKeywordsInputComponent) keywordsInput; 

Xem thêm https://stackoverflow.com/a/35209681/217408

Gợi ý:
keywordsInput không được thiết lập trước ngAfterViewInit() được gọi là

+0

Nếu chưa được đặt trước, bạn đặt sau? – Demodave

+0

Nếu bạn có nghĩa là 'keywordsInput', thì bạn không tự đặt nó, nó được thiết lập bởi Angulars change detection. –

+1

cảm ơn bạn. nó làm việc cho tôi. – knigalye

Các vấn đề liên quan