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

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

Ng-run Example

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

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