【问题标题】:How to detect when a view element is rendered in Angular?如何检测视图元素何时在 Angular 中呈现?
【发布时间】:2018-08-08 17:31:22
【问题描述】:

我的设置是一个带有可点击行的 Angular Material 数据表。单击一行时,其内容将显示在textarea 中以供编辑。我唯一的问题是,我尝试将输入焦点移动到显示的textarea。我尝试使用@ViewChild 来执行此操作,但稍后会在单击处理程序已执行时填充它。

一些代码,用于说明:

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:

<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 中找不到合适的事件处理程序

【问题讨论】:

    标签: javascript angular typescript angular-material


    【解决方案1】:

    在设置焦点之前,您必须等待区域稳定下来。

    它可以像在角材料中使用的那样完成:

    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

    【讨论】:

    • 在设置this.selected 之后,他是否可以通过使用ChangeDetectofRef.detectChanges() 强制更改检测来获得类似的结果?
    • @ConnorsFan 它将为当前组件及其所有子组件运行额外的更改检测周期。
    猜你喜欢
    • 2011-08-25
    • 2012-04-19
    • 2021-07-11
    • 2017-12-23
    • 1970-01-01
    • 1970-01-01
    • 2015-12-27
    • 2018-07-27
    • 1970-01-01
    相关资源
    最近更新 更多