假设我有一个名为inputComponent
的子组件,它具有一个如下的单个输入元素
@Component({ template: `<input #count [(ngModel)]="item.count" />`})
export class inputComponent implements OnInit {
@Input item;
@ViewChild("count") count : ElementRef ;
focus(){
this.count.nativeElement.focus();
this.count.nativeElement.select();
}
}
我将其包含在父容器中,如下所示
<app-input-component [item]="item" ></app-input-component>
我要实现的目的是选择某个事件的文本输入。 例如
@ViewChild("input") count : inputComponent ;
foo(){
this.item = item ;
this.count.focus();
}
问题是,当我在更改绑定数据(项目)后立即调用焦点更改时,如果我在短暂的超时后调用focus()
时,它没有选择任何悬停功能,则效果很好。
我知道使用setTimeOut
解决问题不是正确的方法。
Stackblitz网址
答案 0 :(得分:0)
据我所知,您尝试在呈现元素之前先获取它。那是不可能的。 我建议您阅读有关Angular中的Lifecycle挂钩的信息。 https://angular.io/guide/lifecycle-hooks
您可以通过在生命周期挂钩-ngAfterViewInit中调用foo()函数来解决此问题。
ngAfterViewInit() {
this.foo();
}
答案 1 :(得分:0)
显然,ngModel
会在模型更改时异步更新视图的值。即<input>
的值直到下一个更改检测周期才更改!
来自ngModel
source code:
/**
* `ngModel` forces an additional change detection run when its inputs change:
* E.g.:
* ```
* <div>{{myModel.valid}}</div>
* <input [(ngModel)]="myValue" #myModel="ngModel">
* ```
* I.e. `ngModel` can export itself on the element and then be used in the template.
* Normally, this would result in expressions before the `input` that use the exported directive
* to have and old value as they have been
* dirty checked before. As this is a very common case for `ngModel`, we added this second change
* detection run.
*
* Notes:
* - this is just one extra run no matter how many `ngModel` have been changed.
* - this is a general problem when using `exportAs` for directives!
*/
const resolvedPromise = Promise.resolve(null);
然后,在更新模型时,视图为updated asynchronously:
private _updateValue(value: any): void {
resolvedPromise.then(
() => { this.control.setValue(value, {emitViewToModelChange: false}); });
}
因此setTimeout确保在更新视图后选择了输入。
如果要避免这种异步行为,可以使用FormControl
代替ngModel
(Demo StackBlitz):
import { Component, Input, ViewChild, ElementRef } from '@angular/core';
import { FormControl } from '@angular/forms';
@Component({
selector: 'hello',
template: `<input #input [formControl]="count" />`,
styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent {
private _item;
@Input() set item(value) {
this._item = value;
this.count.setValue(value.count);
this.focus();
}
get item() {
return this._item;
}
@ViewChild('input') input: ElementRef;
count = new FormControl();
focus() {
this.input.nativeElement.focus();
this.input.nativeElement.select();
}
}
使用这种方法,您无需从父组件中显式调用focus()
;输入更改时,子组件将调用其自己的focus方法。