typescript 通过ngIf在元素出现后聚焦元素

vc9ivgsu  于 2023-05-19  发布在  TypeScript
关注(0)|答案(3)|浏览(243)

我有一个按钮,当点击时,被替换为输入字段和确认按钮,然后当输入完成时,它再次被替换为原始按钮。当这种情况发生时,我希望它在原始按钮出现后聚焦(一些用户要求更好地支持选项卡导航),但我似乎不能让它始终这样做。我能做的最好的就是:

// 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
}

如果我单击或按确认按钮上的回车键,焦点会在原始按钮出现时立即移动到它,但如果我在输入字段中按回车键,按钮会出现,但由于某种原因,它不会获得焦点,直到我移动鼠标。我如何让它立即为双方工作?

xkrw2x1b

xkrw2x1b1#

您可以使用ViewChildrenQueryList.changes事件,以便在将按钮添加到视图或从视图中删除按钮时收到通知。如果QueryList包含button元素,则可以在其上设置焦点。请参阅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.setFocus(); // If the button is already present...
    this.durationButton.changes.subscribe(() => {
      this.setFocus();
    });
  }

  setFocus() {
    if (this.durationButton.length > 0) {
      this.durationButton.first.nativeElement.focus();
    }
  }

  enterDuration() {
    this.enteringDuration = true
  }

  setDuration() {
    this.enteringDuration = false
  }
}
bvjxkvbb

bvjxkvbb2#

我一直在与自己的焦点问题作斗争有一段时间了。在您的情况下,一个很好的解决方案是创建一个自定义指令:

export class AutoFocus implements OnInit {
  constructor(private elementRef: ElementRef) {}

  ngOnInit(): void {
    this.elementRef.nativeElement.focus();
  }
}

并将其放置在#durationButton和Input上。由于它们都使用 *ngIf,因此一旦创建元素,它就会被聚焦。工作示例here
PS.在我的例子中,keyup.enter产生了一些不需要的行为,我宁愿坚持使用keydown.enter

wlwcrazw

wlwcrazw3#

是的,*ngIf和ViewChild不能很好地配合。我做了一个关于ViewChild的课程,并做了一个关于处理 *ngIf的完整部分。
一个选项是使用hidden属性而不是 *ngIf。
另一种选择是绑定到setter(类似于绑定到函数):

相关问题