如何检测何时在Angular中渲染视图元素? [英] How to detect when a view element is rendered in Angular?
问题描述
我的设置是带有可单击行的Angular Material数据表.单击一行后,其内容将在 textarea
中内联显示以进行编辑.我唯一的问题是,我尝试将输入焦点移至所示的 textarea
.我尝试使用 @ViewChild
进行此操作,但是稍后会在单击处理程序已经执行时填充它.
My setup is an Angular Material data table with clickable rows. When a row is clicked, its contents are shown inline in a textarea
for editing. My only problem is, I try to move input focus to the shown textarea
. I tried to do it using @ViewChild
, but it's being populated later, when the click handler has already executed.
一些代码,以说明:
app.component.ts:
app.component.ts:
import {Component, ElementRef, ViewChild} from '@angular/core';
@Component({ selector: 'app-root', templateUrl: './app.component.html' })
export class AppComponent {
columns = ['id', 'def'];
selected: string;
ruleDef: string;
@ViewChild('edit') editArea: ElementRef;
selectRule(rule: Rule) {
this.selected = rule.id;
if (this.editArea) this.editArea.nativeElement.focus();
}
}
interface Rule {id: string, def: string}
app.component.html:
app.component.html:
<mat-table #table [dataSource]="dataSource">
<ng-container matColumnDef="id">
<mat-header-cell *matHeaderCellDef>Rule ID</mat-header-cell>
<mat-cell *matCellDef="let element">{{element.id}}</mat-cell>
</ng-container>
<ng-container matColumnDef="def">
<mat-header-cell *matHeaderCellDef>Rule Definition</mat-header-cell>
<mat-cell *matCellDef="let element">
<mat-form-field *ngIf="element.id === selected">
<code><textarea matInput [(ngModel)]="ruleDef" #edit></textarea></code>
</mat-form-field>
<code *ngIf="element.id !== selected">{{element.def}}</code>
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="columns"></mat-header-row>
<mat-row *matRowDef="let row; columns: columns;" (click)="selectRule(row)"></mat-row>
</mat-table>
在 selectRule()
函数中, editArea
是 undefined
或指向先前选择的行.显然, selectRule()
是放置焦点更改的错误位置,但是我在Angular中找不到合适的事件处理程序
In the selectRule()
function, the editArea
is either undefined
, or points to a row selected previously. Obviously the selectRule()
is a wrong place to put the focus change into, but I couldn't find an appropriate event handler in Angular
推荐答案
在设置焦点之前,您必须等待区域稳定.
You must wait for the zone to settle before setting focus.
可以用与角形材料中相同的方式完成
It could be done the same way as is used in angular material:
import {take} from 'rxjs/operators/take';
constructor(private zone: NgZone) { }
selectRule(rule: Rule) {
this.selected = rule.id;
this.zone.onMicrotaskEmpty.asObservable().pipe(
take(1)
)
.subscribe(() => {
this.editArea.nativeElement.focus();
});
}
Ng-run Example
这篇关于如何检测何时在Angular中渲染视图元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!