在 ngbootstrap 弹出窗口的输入中设置焦点
Set focus in input of ngbootstrap popover
我正在使用 ng-bootstrap 弹出窗口对 table 进行过滤。基于列中数据的类型(整数、字符串、日期、..),我想显示不同类型的过滤选项。这按预期工作,但我还希望在显示弹出窗口时聚焦相应的输入字段。
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 函数中执行此操作,但这对我不适用,因为组件在页面加载时被初始化,而我想要弹出窗口为 displayed/shown
时发生焦点
希望能帮我指明正确的方向
我看到您尝试使用 AfterViewChecked。是的,它会被触发 +150 次,但如果你设置条件则不会:
start;
....
ngAfterViewChecked() {
if(this.start){
this.selectInput();
console.log("checked");
this.start = false;
}
}
并仅在单击弹出窗口切换按钮时将开始设置为真:
<button ...(click)="start = true; p.toggle()">
现在在演示控制台中检查它,它仅在需要时触发并且焦点有效。
我正在使用 ng-bootstrap 弹出窗口对 table 进行过滤。基于列中数据的类型(整数、字符串、日期、..),我想显示不同类型的过滤选项。这按预期工作,但我还希望在显示弹出窗口时聚焦相应的输入字段。
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 函数中执行此操作,但这对我不适用,因为组件在页面加载时被初始化,而我想要弹出窗口为 displayed/shown
时发生焦点希望能帮我指明正确的方向
我看到您尝试使用 AfterViewChecked。是的,它会被触发 +150 次,但如果你设置条件则不会:
start;
....
ngAfterViewChecked() {
if(this.start){
this.selectInput();
console.log("checked");
this.start = false;
}
}
并仅在单击弹出窗口切换按钮时将开始设置为真:
<button ...(click)="start = true; p.toggle()">
现在在演示控制台中检查它,它仅在需要时触发并且焦点有效。