在通过ngIf

时间:2018-07-27 21:56:31

标签: angular typescript focus angular-ng-if

我有一个按钮,单击后将其替换为输入字段和确认按钮,然后在输入完成后将其再次替换为原始按钮。发生这种情况时,我希望它在原始按钮出现后将其焦点对准(某些用户要求更好地支持选项卡导航),但是我似乎无法始终如一地做到这一点。我能做的最好的事情是:

// component.html
<button #durationButton *ngIf="!enteringDuration" (click)="enterDuration()">Enter Duration</button>
<ng-container *ngIf="enteringDuration">
    <input type="number" [(ngModel)]="duration" (keyup.enter)="setDuration()">
    <button (click)="setDuration()">&#10003;</button>
</ng-container>

// component.ts
@ViewChild("durationButton") durationButton: ElementRef
duration: number
enteringDuration = false
shouldFocusDurationButton = false

ngAfterContentChecked () {
    if (this.shouldFocusDurationButton && this.durationButton) {
        this.shouldFocusDurationButton = false
        this.durationButton.nativeElement.focus()
    }
}

enterDuration () {
    this.enteringDuration = true
}
setDuration () {
    this.enteringDuration = false
    this.shouldFocusDurationButton = true
}

如果我单击或按下确认按钮上的Enter键,焦点将在显示时立即移至原始按钮,但是如果我在输入字段中按Enter键,则该按钮出现,但由于某种原因,直到我点击按钮移动鼠标。如何使两者立即生效?

2 个答案:

答案 0 :(得分:1)

当按钮添加到视图中或从视图中删除时,您可以使用ViewChildrenQueryList.changes事件得到通知。如果QueryList包含按钮元素,则可以对其设置焦点。有关演示,请参见this stackblitz。建议:您可能想做些类似的事情,以在焦点变为可见时将焦点设置在输入字段上。

import { Component, ViewChildren, ElementRef, AfterViewInit, QueryList } from '@angular/core';
...

export class AppComponent implements AfterViewInit {

  @ViewChildren("durationButton") durationButton: QueryList<ElementRef>;

  enteringDuration = false

  ngAfterViewInit() {
    this.durationButton.changes.subscribe((button) => {
      if (button.length > 0) {
        button.first.nativeElement.focus();
      }
    });
  }

  enterDuration() {
    this.enteringDuration = true
  }

  setDuration() {
    this.enteringDuration = false
  }
}

答案 1 :(得分:0)

是的,* ngIf和ViewChild不能很好地玩。我在ViewChild上做了一门课程,并且仅在处理* ngIf时做了整个部分。

一种选择是使用hidden属性而不是* ngIf。

另一种选择是绑定到setter(类似于您绑定到函数的方式):

enter image description here