问题描述
我正在尝试访问本机元素,以便在单击另一个元素时将其聚焦(很像html属性"for"-for不能在这种类型的元素上使用.
I'm trying to access a native element in order to focus on it when another element is clicked (much like the html attribute "for" - for cannot be used on elements of this type.
但是我得到了错误:
我尝试在ngAfterViewInit()
中console.log nativeElement,以便加载它,但仍然会引发错误.
I try to console.log the nativeElement in ngAfterViewInit()
so that it is loaded but it still throws the error.
我还可以在click事件处理程序中访问nativeElement,以便在单击另一个元素时可以使该元素聚焦-这可能是对其造成破坏的原因,因为它在视图加载之前就已编译了.
I also access nativeElement in the click event handler, so that I can focus the element when another element is clicked - is this possibly what is mucking it up, because it compiles before the view has loaded?.
例如:
ngAfterViewInit() {
console.log(this.keywordsInput.nativeElement); // throws an error
}
focusKeywordsInput(){
this.keywordsInput.nativeElement.focus();
}
完整代码:
所使用的html模板的相关部分:
relevant part of the html template being used:
<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:
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模板(可能不相关):
full html template (probably irrelevant):
<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
请注意,由于模板引用名称中不允许使用-
,因此应使用驼峰式大小写.
Note that camel case should be used, since -
is not allowed in template reference names.
@ViewChild()
支持模板变量的名称为字符串:
@ViewChild()
supports names of template variables as string:
@ViewChild('keywordsInput') keywordsInput;
或组件或指令类型:
@ViewChild(MyKeywordsInputComponent) keywordsInput;
另请参见 https://stackoverflow.com/a/35209681/217408
提示:
在调用ngAfterViewInit()
之前未设置keywordsInput
Hint:keywordsInput
is not set before ngAfterViewInit()
is called
这篇关于@viewChild不起作用-无法读取未定义的属性nativeElement的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!