ng-bootstrap - 当使用 enter 键打开新的 NgbDropdowns 时,如何关闭先前打开的 NgbDropdowns?
问题描述
我是 NgbDropdown 和相关 ng-bootstrap 代码的新手,当使用回车键打开新的 NgbDropdowns 时,我无法弄清楚如何关闭所有以前的 NgbDropdowns。
我在我的 Angular 项目的一个页面上创建了许多 NgbDropdowns,我发现当我从下拉按钮单击到下拉按钮时,之前打开的下拉菜单会关闭;但是,如果我从一个打开的下拉菜单中选择 TAB 到另一个下拉按钮并使用 enter 键打开第二个下拉菜单,这可能是可访问性所需要的,第一个下拉菜单不会关闭。我留下了两个相互重叠的下拉菜单。
可以在https://ng-bootstrap.github.io/#/components/dropdown/examples的主要 NgbDropdown 示例页面上复制此序列:在不同的按钮上(顶部的第一个示例。)
顺序: 1. Tab 切换到“Toggle Dropdown” 2. 按回车键打开下拉列表 3. Tab 通过下拉选项,再加一次,这样您就切换到了“切换下拉”按钮。4. 按回车键 5. 两个下拉菜单将同时打开。
因此,当在其他按钮上按下回车键时,显然关闭先前单击下拉菜单的代码不起作用。没有找到太多关于可以在 typescript 中使用各种 Ngb 对象做什么的文档,我不知道在使用 enter 键打开新下拉列表时如何关闭所有以前的下拉列表。我能想到的只有:
1) 遍历 ts 文件中的所有下拉列表,在打开最新的之前关闭它们。如果这是最好的解决方案,我看不出有任何方法可以循环打开一组下拉列表。作为 NgbSolution 的一部分,我是否可以使用这样的对象/数组,还是我必须自己将每个对象/数组添加到数组中?
2)当在按钮上按下回车键时触发点击事件。同样,我不知道如何让一个事件在 NgbDropdown 对象上触发另一个事件。
任何指针将不胜感激。我没有在这里发布我的代码,因为它与上面引用的基本示例相同。
解决方案
对于您的建议 #1(遍历所有下拉菜单并关闭它们),您可以按如下方式实现它:
- 在您的 HTML 中,使用模板引用变量(
#
语法)将每个下拉列表声明为 DOM 变量:
<div ngbDropdown class="d-inline-block" #dd1="ngbDropdown">
...
</div>
- 如下添加一个
click
处理程序button
。这允许您将对下拉列表的引用传递给单击处理程序调用的函数:
<button class="btn btn-outline-primary" id="dropdownBasic1" ngbDropdownToggle (click)="closeOthers(dd1)">Toggle dropdown</button>
下拉列表的完整 HTML 应如下所示:
<div ngbDropdown class="d-inline-block" #dd1="ngbDropdown">
<button class="btn btn-outline-primary" id="dropdownBasic1" ngbDropdownToggle (click)="closeOthers(dd1)">
Toggle dropdown
</button>
<div ngbDropdownMenu aria-labelledby="dropdownBasic1">
<button ngbDropdownItem>Action - 1</button>
<button ngbDropdownItem>Another Action</button>
<button ngbDropdownItem>Something else is here</button>
</div>
</div>
- 添加以下内容作为 Typescript 组件的类变量。这允许您从 Typescript 文件中引用组件中显示的所有下拉列表:
@ViewChildren(NgbDropdown) dropdowns: QueryList<NgbDropdown>;
click
向您的 Typescript 组件添加一个函数:
closeOthers(clickedDropdown: NgbDropdown) {
// Close all dropdowns
this.dropdowns.toArray().forEach(el => {
el.close();
});
// Open the dropdown that was clicked on
clickedDropdown.open();
}
现在,每当您单击下拉菜单(或通过 Tab 键和按回车键选择它)时,它都会调用以下closeOthers
函数:
- 关闭所有下拉菜单
- 打开被点击的下拉菜单
请参阅此 StackBlitz以获取工作演示。
@Dordrecht - 我将为您在下面的评论中提到的功能采取的方法是创建如下服务:
export class ModalNotificationService {
private _closeModals: Subject<void> = new Subject<void>();
private _closeModals$: Observable<void> = this._closeModals.asObservable();
public emitCloseModalEvent() {
this._closeModals.next();
}
get closeModals$(): Observable<void> {
return this._closeModals$;
}
}
该服务将被注入任何具有模态的组件中,并且这些组件将订阅可观察closeModals$
对象,然后在它们自己的组件中关闭模态。修改closeOthers
方法以调用新服务的emitCloseModalEvent
方法来通知所有其他组件。
推荐阅读
- mysql - 使用 Cron 将数据从 mysql 数据库导出到 CSV,然后将所有数据获取到 bigquery 表
- python - 使用二元分类器模型将数据分为 3 类
- angular - ng-bootstrap Carousel 隐藏分页指示器,“NgbCarouselConfig”类型上不存在“showNavigationIndicators”
- android - 删除 EditText 上下文菜单颜色
- swift - 如何使用功能性 reactSwift 泛化来自属性的表单输入?
- ios - UIImagePickerController swift的问题
- python - 重新采样滚动绘图实时数据以仅显示实际可见的点以提高性能(PyQtGraph)
- r - 将 dplyr 中的领先或滞后与其他变量结合使用
- sql - 该列在选择列表中无效,因为它不包含在聚合函数或 GROUP by 子句中
- bazel - 如何在 Bazel 中创建和使用自定义构建标志?