将ng-select过滤器输入聚焦在下拉菜单上

时间:2019-05-22 14:40:46

标签: angular angular-ngselect

我正在使用ng-select,并定义了包含输入的自定义过滤器标题模板。

当希望为选择打开下拉菜单时,我希望输入能够获得焦点,但是我不知道该怎么做。

我在这里有一个示例-> https://stackblitz.com/edit/angular-playground-f57jog

我确实尝试附加到ng-select (open)输出并在输入元素上调用focus(),但这对我来说失败。

这里正确的方法是什么? 谢谢

5 个答案:

答案 0 :(得分:3)

我将创建特殊指令并在需要的地方重复使用它:

@Directive({
  selector: '[appAutofocus]'
})
export class AutofocusDirective implements OnInit {

  constructor(private el: ElementRef) {
  }

  ngOnInit() {
    this.el.nativeElement.focus();
  }
}

html

<input appAutofocus ... />

因此它应该可以在Chrome,Firefox等环境中使用。

Forked Stackblitz

答案 1 :(得分:1)

您可以使用此方法:

在您的html中:

<ng-select #api [items]="cars"
          [virtualScroll]="true"
          [loading]="loading"
          bindLabel="brand"
          bindValue="id"
          (scroll)="onScroll($event)"
          (scrollToEnd)="onScrollToEnd()"
          [dropdownPosition]="'bottom'"
          [searchable]="false"
          [(ngModel)]="selectedCar2"
          [searchFn]="customSearchFn"
          (change)="onChange($event)"
          (open)="focusInputField()">

请注意(打开)已更改。

在.ts文件中添加:

    @ViewChild('filterInput') filterInput:ElementRef;


    focusInputField() {
      setTimeout(() => {
      this.filterInput.nativeElement.focus()
      }, 10)
    }

这对Chrome和Firefox均适用。

答案 2 :(得分:0)

只需使用ViewChildren和susbcribe进行更改,然后集中精力即可。是的。

@ViewChildren('filterInput') filterInput : QueryList<ElementRef>;

onOpen()
{
  this.filterInput.changes.subscribe(res=>{
      this.filterInput.first.nativeElement.focus()
  })
}

在您的.html

<ng-select ...  (open)="onOpen()"></ng-select>

查看您的https://example2.com

答案 3 :(得分:0)

在触发ng-select打开回调与实际呈现filterInput元素之间存在时间问题。您的语法正确,但是当ng-select open发出时,filterInput是未定义的。请从提供的stackblitz中的调试控制台中参考以下错误:

  

错误TypeError:无法读取未定义的属性'nativeElement'

解决此问题的一种方法是延迟对打开回调中未定义元素的调用。下面我通过1)通过@ViewChild捕获filterInput ElementRef来完成上述工作,2)将当前的焦点逻辑重构为组件内的方法并增加了250 ms的延迟,以及3)使用ng-select组件open调用所述方法事件发射器。如果愿意,我也提供了第2步的RxJS替代方法。


app.component.ts

// 1
@ViewChild('filterInput') filterInput: ElementRef;

// 2
setFilterFocus() {
  setTimeout((() => { this.filterInput.nativeElement.focus() }).bind(this), 250)
}

app.component.html

<!-- 3 -->
<ng-select #api [items]="cars"
          [virtualScroll]="true"
          [loading]="loading"
          bindLabel="brand"
          bindValue="id"
          (scroll)="onScroll($event)"
          (scrollToEnd)="onScrollToEnd()"
          [dropdownPosition]="'bottom'"
          [searchable]="false"
          [(ngModel)]="selectedCar2"
          [searchFn]="customSearchFn"
          (change)="onChange($event)"
          (open)="setFilterFocus()">

重新访问第2步-改用RxJS

app.component.ts其他导入

import { of } from 'rxjs';
import { delay, tap } from 'rxjs/operators';

app.component.ts setFilterFocus RxJS样式

setFilterFocus() {
    of(null)
      .pipe(
        delay(250), 
        tap(() => this.filterInput.nativeElement.focus()))
      .subscribe();
}

答案 4 :(得分:-1)

autofocus属性添加到您的input标记

您的代码将如下所示:

<input autofocus #filterInput style="width: 100%; line-height: 24px" type="text" (input)="api.filter($event.target.value)"/>

stackbliz演示here的更新版本

希望它会有所帮助:)