将焦点设置在ngbootstrap popover的输入中

时间:2017-10-23 11:45:51

标签: angular ng-bootstrap

我使用ng-bootstrap popover对表进行过滤。基于列中数据的类型(int,string,date,..),我想显示不同类型的过滤选项。这可以按预期工作,但我还希望在显示弹出窗口时聚焦相应的输入字段。

ng-boostrap popover暴露了一个名为(显示)的输出,我试图使用它来调用一个函数来聚焦我的输入,这似乎不起作用。

如果我从ngAfterViewChecked()调用相同的函数,它按预期聚焦,但由于此函数被多次调用,它似乎不是一个非常好的解决方案(在我自己的网站上它被调用大约150次每次切换弹出窗口)。我不确定为什么会这么多次被召唤,但这不是问题的重点。

我创建了一个显示我的问题的plunker: http://plnkr.co/edit/fr0nI1GiRT22UWXaNZwJ?p=preview

HTML:

<div style="display:flex; align-items:center; justify-content:center"><button type="button" class="btn btn-outline-secondary" placement="bottom"
        [ngbPopover]="popContent" popoverTitle="Popover on bottom" (shown)="selectInput()" container="body"  triggers="manual" #p="ngbPopover" (click)="p.toggle()">
  Popover on bottom
</button>
</div>

<ng-template #popContent>
  <div class="filter-popover">
    <div>
      <label for="filterbox">Filter: </label>
      <input id="filterbox" [(ngModel)]="appliedFilter" class="form-control form-control-sm" [focus]="focusSettingEventEmitter" />
    </div>
    <div class="popover__controls d-flex justify-content-end">
      <button class="btn btn-sm btn-success" (click)="p.close()">OK</button>
      <button class="btn btn-sm btn-danger" (click)="p.close()">Cancel</button>
    </div>
  </div>
</ng-template>

组件:

import { Component, Input, Output, OnChanges, EventEmitter, HostListener, ViewChild, ViewChildren, AfterViewInit, AfterViewChecked } from '@angular/core';

@Component({
  selector: 'ngbd-popover-basic',
  templateUrl: 'src/popover-basic.html'
})
export class NgbdPopoverBasic implements AfterViewChecked {
      public focusSettingEventEmitter = new EventEmitter<boolean>();

    selectInput() {
        this.focusSettingEventEmitter.emit(true);
    }
    ngAfterViewChecked() {
      //if i call it here it will focus it, but this function is run 150 times on my site (here around 3), so we dont want to do that
      //this.selectInput();
      //console.log("checked")
    }
}

指令:

import { Directive, Input, EventEmitter, ElementRef, Renderer, Inject } from '@angular/core';

@Directive({
    selector: '[focus]'
})
export class FocusDirective {
    @Input('focus') focusEvent: EventEmitter<boolean>;

    constructor( @Inject(ElementRef) private element: ElementRef, private renderer: Renderer) {
    }

    ngOnInit() {
        this.focusEvent.subscribe((event:any) => {
            this.renderer.invokeElementMethod(this.element.nativeElement, 'focus', []);
        });
    }
}

从我读过的其他用户关于聚焦输入的内容来看,你应该在函数AfterViewInit中做到这一点,但这不适用于我,因为组件在页面加载时被初始化,我想要一旦弹出显示/显示

,就会发生焦点

愿意帮助我指出正确的方向

1 个答案:

答案 0 :(得分:0)

我发现您已尝试使用AfterViewChecked。这是真的,它会被点燃+150次,但如果你设定条件则不会:

start;

....    
ngAfterViewChecked() {
  if(this.start){
     this.selectInput();
     console.log("checked");
     this.start = false;
  }
}   

并仅在单击popover切换按钮时设置start tot:

  <button ...(click)="start = true; p.toggle()">

现在在演示控制台中查看它,它只在需要时被解雇并且焦点有效。

<强> DEMO