专注于 ngFor 内部的输入



当用户单击按钮时,addElement方法会将对象推送到elements数组,并创建新的输入字段。是否可以专注于新创建的元素?输入没有唯一的 ID。

模板:

<div *ngFor="let foo of elements">
<input class="input" value="{{ foo.value }}" />
</div>
<button (click)="addElement()"></button>

方法:

public addElement() {
this.elements.push({ value: 'new' });
}

我在这个应用程序中使用 Angular 9。

您需要通过ViewChildren装饰器查询所有输入,然后每次调用addElement时也会调用ngAfterViewChecked。因此,您可以使用此钩子来聚焦上次已创建的输入。

<div *ngFor="let foo of elements">
<input 
#input 
class="input" 
[value]="foo.value"
/>
</div>
<button (click)="addElement()"></button>
@ViewChildren('input') inputs: QueryList<ElementRef>;
addElement() {
this.elements.push({ value: 'new' });
}
ngAfterViewChecked() {
this.inputs.last.nativeElement.focus();
}

否则,您可以自己检查,不要依赖生命周期钩子,因为ngAfterViewChecked中的此逻辑可能会影响应用程序中的 smth:

@ViewChildren('input') inputs: QueryList<ElementRef>;
constructor(private changeDetectorRef: ChangeDetectorRef) {
}
addElement() {
this.elements.push({ value: 'new' });
/* run change detection manually to create input element and have access to the last input */
this.changeDetectorRef.detectChanges();
this.inputs.last.nativeElement.focus();
}
<小时 />

https://angular.io/api/core/ViewChildren#description

https://angular.io/guide/lifecycle-hooks#lifecycle-event-sequence

ngFor 中的角度元素可以使用ViewChildren访问。

您可以通过以下方式更新addElement函数以实现结果。

@ViewChildren("row") rows;
public addElement() {
this.elements.push({ value: "new" });
setTimeout(() => {
this.rows.last.nativeElement.focus();
}, 0);
}

并更新您的 ngFor 模板,如下所示:

<div *ngFor="let foo of elements">
<input #row class="input" value="{{ foo.value }}" />
</div>

这是堆栈闪电战的示例: https://stackblitz.com/edit/angular-ivy-xtkvaz

您可以通过跟踪div 子组件的任何更改来实现此目标。每次创建或刷新div时,请将焦点放在最后一个input子项上。

为此,您需要:

  • 一个指令div向容器添加一些行为逻辑
  • 一个指令来标识每个input标签

这样,您的模板可以是:

<div track-focus *ngFor="let foo of elements">
<input auto-focus ... />
</div>
<button (click)="addElement()">Add</button>
@Directive({
selector: 'input[auto-focus]',
})
export class InputAutoFocusDirective {}
@Directive({
selector: '[track-focus]',
})
export class TrackFocusDirective implements AfterContentInit {
@ContentChildren(InputAutofocusDirective, {
read: ElementRef,
})
children: QueryList<InputAutoFocusDirective>;
ngAfterContentInit() {
const input = (this.children.last as ElementRef)
.nativeElement as HTMLElement;
if (input) {
input.focus();
}
}
}

在这里,您有一个可重复使用的解决方案。

相关内容

  • 没有找到相关文章

最新更新