问题
I’m working in an angular 6 application. I have a textarea that I’d like to give focus to as soon as the page loads. I’m not able to do so.
Here is what the page looks like:
<div fxLayoutAlign="begin">
<button mat-button color="primary" [routerLink]="['/Administration']">
<i class="far fa-arrow-alt-circle-left"></i> Back to Administration
</button>
</div>
<div class="app-loading" *ngIf="_loading">
<mat-spinner diameter=100></mat-spinner>
</div>
<div *ngIf="!_loading">
<div class="knowledgeBody">
<div *ngIf="_mode === 'view'">
{{ _knowledgeText }}
<div fxLayoutAlign="end">
<button mat-button (click)="edit_clicked()" disabled="{{ _knowledgeText.trim().length === 0 }}">
<i class="fas fa-edit"></i> Edit
</button>
</div>
</div>
<div *ngIf="_mode !== 'view'">
<textarea matInput [(ngModel)]="_knowledgeText" cdkTextareaAutosize #knowledgeTextarea>
{{ _knowledgeText }}
</textarea>
<div fxLayoutAlign="end">
<button mat-button (click)="save_clicked()" disabled="{{ _knowledgeText.trim().length === 0 }}">
<i class="fas fa-save"></i> Save
</button>
</div>
</div>
</div>
</div>
The textarea of interest is #knowledgeTextarea.
Here’s the component for the page:
@Component({
selector: 'app-knowledge',
templateUrl: './knowledge.component.html',
styleUrls: ['./knowledge.component.scss']
})
export class KnowledgeComponent implements OnInit {
private _mode : string;
private _loading : boolean;
private _knowledgeId : string;
private _knowledgeText : string;
private _description : string;
private _groupPK : string;
@ViewChild('knowledgeTextarea') knowledgeTextarea : ElementRef;
constructor(private _activatedRoute : ActivatedRoute,
private _watermelonService : WatermelonService,
private _logService : LoggingService,
private _dialog: MatDialog) {
this._loading = true;
}
ngOnInit() {
…
this.knowledgeTextarea.nativeElement.focus();
…
}
…
}
When I run this, I get the following error:
Cannot read property ‘nativeElement’ of undefined.
I’ve read that this can happen when you reference an element on the page using the # identification (#knowledgeTextarea) inside an *ngIf block. So this…
<div *ngIf="_mode !== 'view'">
<textarea matInput [(ngModel)]="_knowledgeText" cdkTextareaAutosize #knowledgeTextarea>
{{ _knowledgeText }}
</textarea>
</div>
…will not work.
But then what is the alternative?
I tried this…
<div *ngIf="_mode !== 'view'">
<textarea matInput [(ngModel)]="_knowledgeText" cdkTextareaAutosize #knowledgeTextarea>
{{ _knowledgeText }}
</textarea>
{{ knowledgeTextarea.focus() }}
</div>
…which worked but then I got a ExpressionChangedAfterItHasBeenCheckedError, which JB Nizet told me not to do here: Getting ExpressionChangedAfterItHasBeenCheckedError error.
If there is another way of doing this, please let me know. All I want is to be able to give the textarea focus when the page loads. Any way of accomplishing that would be greatly appreciated. Thanks.
回答1:
The issue is accessing the element before it was rendered. You must ensure that the content is rendered before it is being used. So instead of accessing it inside ngOnInit
, you should do in ngAfterViewInit
.
@ViewChild('knowledgeTextarea') knowledgeTextarea: ElementRef;
ngAfterViewInit() {
this.knowledgeTextarea.nativeElement.focus();
}
Working sample is here - https://stackblitz.com/edit/angular-jjyfwf
来源:https://stackoverflow.com/questions/53544625/elementref-is-undefined