I'm trying to understand the best approach to wait for the template to update in an Angular 2 application after the model has changed.
@Component{
template : `<button type="button" (click)="handleClick()">Click</button>
<div *ngIf="!hidden">
<input type='text' #eleInput/>
</div>`
}
export class Sample{
private hidden: boolean = true;
@ViewChild('eleInput') eleInput: ElementRef;
constructor(){}
handleClick(){
this.hidden = false;
//nativeElement is undefined here
this.eleInput.nativeElement.focus();
//nativeElement is defined here
setTimeout(() => {
this.eleInput.nativeElement.focus();
});
}
}
Using setTimeout in the above code seems hacky, so I'd like to know if there's a better approach.
Thanks!
I'm trying to understand the best approach to wait for the template to update in an Angular 2 application after the model has changed.
@Component{
template : `<button type="button" (click)="handleClick()">Click</button>
<div *ngIf="!hidden">
<input type='text' #eleInput/>
</div>`
}
export class Sample{
private hidden: boolean = true;
@ViewChild('eleInput') eleInput: ElementRef;
constructor(){}
handleClick(){
this.hidden = false;
//nativeElement is undefined here
this.eleInput.nativeElement.focus();
//nativeElement is defined here
setTimeout(() => {
this.eleInput.nativeElement.focus();
});
}
}
Using setTimeout in the above code seems hacky, so I'd like to know if there's a better approach.
Thanks!
Share Improve this question asked Oct 16, 2016 at 16:17 ChristopherChristopher 1051 silver badge4 bronze badges 1- Look into Animations... – Sasxa Commented Oct 16, 2016 at 16:23
2 Answers
Reset to default 10There is no way to wait for the template to update.
You can inject ChangeDetectorRef
constructor(private cdRef:ChangeDetectorRef) {}
and then call
this.cdRef.detectChanges();
As far as I know the template is updated when the call returns.
Use [hidden]
instead of ngIf
.
NgIf
removes element. That's the reason this.eleInput.nativeElement.focus();
doesn't work without setTimeout
because this.eleInput.nativeElement.focus();
line runs immediately before DOM element is/bees set for the further reference.
When [hidden]
property doesn't remove DOM element. It just shows and hides an element. So DOM element reference will be there and you nativeElement won't be undefined. So, it will work.
<div [hidden]="hidden"> //<<<===use hidden instead of *ngIf
<input type='text' #eleInput/>
</div>
private hidden: boolean = true;
@ViewChild('eleInput') eleInput: ElementRef;
constructor(){}
handleClick(){
this.hidden = false;
this.eleInput.nativeElement.focus(); //<<<===now this will work.
}
}