如何检测何时在 Angular 中呈现视图元素? [英] How to detect when a view element is rendered in Angular?

查看:20
本文介绍了如何检测何时在 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 示例

这篇关于如何检测何时在 Angular 中呈现视图元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆