【问题标题】:Set focus in input of ngbootstrap popover在 ngbootstrap popover 的输入中设置焦点
【发布时间】:2017-10-24 02:52:52
【问题描述】:

我正在使用 ng-bootstrap 弹出框对表格进行过滤。根据列中数据的类型(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 中执行此操作,但这不适用于我,因为该组件在页面加载时被初始化,我希望将焦点移到一旦显示/显示弹出框就会发生

希望有人能帮我指明正确的方向

【问题讨论】:

    标签: angular ng-bootstrap


    【解决方案1】:

    我了解到您已尝试使用 AfterViewChecked。是的,它会被触发 +150 次,但如果你设置一个条件则不会:

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

    并且仅在单击弹出框切换按钮时才将 start tot 设置为 true:

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

    现在在演示控制台中检查它,它只在需要时触发并且焦点有效。

    DEMO

    【讨论】:

    • 一个很好的解决方法,我还意识到显示的是在模板渲染之前发出的。如果我在选择输入函数中设置超时它也可以工作。
    • 我试图遵循这一点,但我收到此错误 - 无法读取未定义的属性“订阅”。请关注这个问题stackoverflow.com/questions/57959569/…
    猜你喜欢
    • 2018-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-25
    相关资源
    最近更新 更多