新闻详情

新闻详情

首页 / 资讯中心 / 详情

Angular ARIA Menu API 指南:解读 @angular/aria_menu 的 ngMenu 公开接口与源码实现

发布时间:2026/9/11 21:34:00来源:尧图网络
Angular ARIA Menu API 指南:解读 @angular/aria_menu 的 ngMenu 公开接口与源码实现
Angular ARIA Menu API 指南解读 angular/aria_menu 的 ngMenu 公开接口与源码实现【免费下载链接】componentsComponent infrastructure and Material Design components for Angular项目地址: https://gitcode.com/GitHub_Trending/co/components本文基于当前仓库生成的 API 报告 goldens/aria/menu/index.api.md 展开系统讲解angular/aria_menu包的完整公开 API 面Menu、MenuItem、MenuTrigger、MenuBar、MenuContent五个指令以及MENU_COMPONENT注入令牌。文中逐项说明每个输入/输出信号的类型、默认值、语义并结合 src/aria/menu 下的真实源码与 menu.spec.ts 测试用例揭示这些 API 背后的信号化实现与键盘导航行为。读完本文你将能够准确使用ngMenu系列指令构建可访问的下拉菜单与菜单栏并学会用MenuHarness/MenuItemHarness编写组件测试。一、API 报告是什么goldens/aria/menu/index.api.md 的定位goldens/aria/menu/index.api.md是 API Extractor 针对angular/aria_menu包自动生成的公开 API 快照文件文件头部明确标注 Do not edit this file。它通过public标签标记所有导出的公开符号精确记录每个类的字段类型、信号装饰器、指令选择器与宿主行为是校验包导出面是否发生破坏性变化的黄金基线也是开发者查阅该包公开契约的第一手资料。从报告可以看到angular/aria_menu是 Angular Components 中ARIA 基础组件系列src/aria/下包含 accordion、combobox、grid、listbox、menu、tabs、toolbar、tree 等的一员与 Material 组件不同它只提供行为与 ARIA 语义不附带任何视觉样式Menu的类注释将其定位为向用户提供菜单项选择列表的无样式指令。二、包结构与核心概念菜单由四类指令协同工作angular/aria_menu的源码位于 src/aria/menu目录结构如下menu.ts—Menu指令[ngMenu]菜单容器menu-item.ts—MenuItem指令[ngMenuItem]菜单项menu-trigger.ts—MenuTrigger指令[ngMenuTrigger]菜单触发器menu-bar.ts—MenuBar指令[ngMenuBar]菜单栏容器menu-content.ts—MenuContent指令ng-template[ngMenuContent]延迟渲染内容menu-tokens.ts—MENU_COMPONENT注入令牌public-api.ts/index.ts— 导出入口一个最基础的下拉菜单由三部分拼装而成示例取自 menu.ts 的类注释button ngMenuTrigger [menu]myMenuOptions/button div ngMenu #myMenungMenu div ngMenuItem valueStarStar/div div ngMenuItem valueEditEdit/div div ngMenuItem valueMore [submenu]subMenuMore/div /div div ngMenu #subMenungMenu div ngMenuItem valueSub Item 1Sub Item 1/div div ngMenuItem valueSub Item 2Sub Item 2/div /divngMenu内部通过ngMenuItem的submenu输入相互嵌套形成多级子菜单ngMenuTrigger则负责打开/关闭关联菜单。所有指令的导出名exportAs与选择器见下表指令选择器exportAs对应文件MenuV[ngMenu]ngMenumenu.tsMenuItemV[ngMenuItem]ngMenuItemmenu-item.tsMenuTriggerV[ngMenuTrigger]ngMenuTriggermenu-trigger.tsMenuBarV[ngMenuBar]ngMenuBarmenu-bar.tsMenuContentng-template[ngMenuContent]ngMenuContentmenu-content.ts所有类都携带一个泛型参数V代表菜单项value的类型选择菜单后通过itemSelected输出该值。全包通过 menu-tokens.ts 中的MENU_COMPONENT注入令牌InjectionTokenMenuany | MenuBarany让子级MenuItem在 DI 层拿到父容器实例从而注册进父级的SortedCollection。三、Menu 指令ngMenu完整输入输出与信号化实现3.1 公开 API 速查表根据 API 报告MenuV的完整公开成员如下成员类型默认值说明idInputSignalstring由_IdGenerator生成ng-menu-前缀菜单唯一 ID同时写为宿主id属性wrapInputSignalWithTransformbooleantrue键盘导航到边界时是否循环回绕typeaheadDelayInputSignalnumber500输入搜索typeahead缓冲被清空的毫秒延迟disabledInputSignalWithTransformbooleanfalse是否禁用整个菜单softDisabledInputSignalWithTransformbooleantrue软禁用菜单对用户仍可点开但所有项不可选中expansionDelayInputSignalnumber100悬停展开子菜单的毫秒延迟itemSelectedOutputEmitterRefV \| undefined—菜单项被选中时触发载荷为该项valuepreserveContent来自宿主指令DeferredContentAware—是否在菜单关闭后保留已渲染内容elementHTMLElement—宿主元素引用visibleSignalboolean—菜单当前是否可见tabIndexSignal-1 \| 0—菜单的 tabindexroving tabindex 模式parentWritableSignalMenuItemV \| MenuTriggerV \| undefinedundefined父级菜单项或触发器textDirectionWritableSignalDirection来自DirectionalityLTR/RTL 方向上下文close()方法—编程式关闭菜单宿主绑定见 menu.tsrolemenu、tabindex、aria-disabled、data-visible并统一把keydown、mouseover、mouseout、focusout、focusin、click事件转发给内部的MenuPattern处理。3.2 输入信号的默认值与语义源码依据Menu的所有输入都采用 Angular 信号形式定义menu.tsreadonly id input(inject(_IdGenerator).getId(ng-menu-, true)); readonly wrap input(true, {transform: booleanAttribute}); readonly typeaheadDelay inputnumber(500); // Picked arbitrarily. readonly disabled input(false, {transform: booleanAttribute}); readonly softDisabled input(true, {transform: booleanAttribute}); readonly expansionDelay inputnumber(100); // Arbitrarily chosen.值得注意的细节wrap、disabled、softDisabled均使用booleanAttribute转换器因此模板中可写div ngMenu wrapfalse或只写属性名div ngMenu disabled。softDisabled默认是true与 CDK 菜单相反——设计意图是菜单可以正常打开但选中操作被拦截适合确认弹窗内禁止操作等场景。typeaheadDelay与expansionDelay的默认值在源码注释中明确标注为任意选取Picked arbitrarily即 500ms 与 100ms 并非规范强制值可按需覆盖。id未显式提供时由angular/cdk/a11y的_IdGenerator生成形如ng-menu-0的唯一值保证aria-controls关联可靠。3.3 可见性与焦点恢复visible、tabIndex是两个由computed()派生的信号menu.ts直接透传_pattern的状态。构造函数中的afterRenderEffectmenu.ts在菜单变为可见时自动把焦点移到当前活动项上——这正是从子菜单返回时焦点正确复原、悬停进入子菜单时聚焦首项的实现来源。而_collectionSortedCollection在afterNextRender后通过startObserving监听 DOM 变化因此动态增删、打乱菜单项都能实时反映到导航顺序上menu.spec.ts的 should update item order correctly after items are shuffled 用例即验证了这一点。四、MenuItem 指令ngMenuItem值、角色与子菜单4.1 公开 API 速查表MenuItemV的公开成员API 报告 menu-item.ts成员类型默认值说明idInputSignalstringng-menu-item-前缀生成菜单项唯一 IDvalueInputSignalV \| undefinedundefined选中时通过itemSelected发出的载荷disabledInputSignalbooleanfalse禁用该项searchTermModelSignalstring输出searchTermChange该项的类型搜索词参与 typeahead 匹配roleInputSignalmenuitem \| menuitemradio \| menuitemcheckboxmenuitemARIA 角色submenuInputSignalMenuV \| undefinedundefined关联的子菜单activeSignalboolean—是否为当前活动项写data-activeexpandedSignalboolean \| null—子菜单是否展开写aria-expandedhasPopupSignalboolean—是否带弹出子菜单写aria-haspopupparentMenuV \| MenuBarV \| null—通过MENU_COMPONENT注入的父容器open()/close()方法—打开聚焦首项/关闭子菜单宿主绑定menu-item.ts会根据状态自动写role、tabindex、aria-haspopup、aria-expanded、aria-disabled、aria-controls指向子菜单 id。这意味着无需手写任何 ARIA 属性即可获得完整语义。4.2 三种角色与多选/单选通过切换role输入同一个ngMenuItem可以承担三种语义menuitem默认普通命令项点击触发itemSelectedmenuitemcheckbox复选框语义支持选中态切换menuitemradio单选按钮语义。这与 CDK/Material 菜单的静态角色不同——MenuItemPattern位于src/aria/private会根据角色动态决定键盘交互如 Space/Enter 切换勾选态。测试示例可参考 menu.spec.ts 中针对三种角色行为的用例组。4.3 注册与校验MenuItem在ngOnInit时调用this.parent?._collection.register(this)注册进父容器的有序集合ngOnDestroy时反注册menu-item.ts。开发模式下若检测到ngMenuItem没有放在ngMenu/ngMenuBar内会在控制台通过reportViolations报出 ngMenuItem must be placed inside an ngMenu or ngMenuBar container. 的错误提示帮助尽早发现结构问题。五、MenuTrigger 指令ngMenuTrigger打开与软禁用MenuTriggerV用于把任意交互元素与ngMenu关联起来menu-trigger.tsbutton ngMenuTrigger [menu]myMenuOpen Menu/button公开成员成员类型默认值说明menuInputSignalMenuV \| undefinedundefined要打开的目标菜单disabledInputSignalWithTransformbooleanfalse硬禁用菜单不可打开softDisabledInputSignalWithTransformbooleantrue软禁用菜单可打开但项不可选中expandedSignalboolean—菜单是否展开写aria-expandedhasPopupSignalboolean—是否带弹出写aria-haspopupopen()/close()方法—编程式开关open会聚焦首项宿主绑定自动管理tabindex、disabled、aria-disabled、aria-haspopup、aria-expanded、aria-controls关联到菜单 id。构造函数里有一个容易被忽略的细节当触发器宿主是button且未显式声明type时会自动补上typebuttonmenu-trigger.ts避免按钮意外触发表单提交——这是实战中非常实用的防御性行为。另外两个effect()会把触发器的_pattern反向注册到菜单的parent从而让菜单知道自己的打开来源。六、MenuBar 指令ngMenuBar水平菜单栏与多选值MenuBarV是始终可见、通常位于窗口顶部的常驻菜单栏容器menu-bar.tsdiv ngMenuBar button ngMenuTrigger [menu]fileMenuFile/button button ngMenuTrigger [menu]editMenuEdit/button /div公开成员与Menu的差异点value是ModelSignalV[]记录当前处于选中态checkbox/radio的菜单项值列表模板中可双向绑定[(value)]同时暴露valueChange输出没有expansionDelay、visible等成员菜单栏不涉及弹出式可见性键盘焦点模式为roving、方向为horizontalMenu是vertical这是两者在 menu-bar.ts 构造MenuBarPattern时传入的关键差异宿主rolemenubar事件转发到MenuBarPattern。disabled、softDisabled、wrap、typeaheadDelay的语义与Menu完全一致默认值相同可复用上文的说明。七、MenuContent 指令延迟渲染子菜单内容MenuContent是一个极简的结构型指令menu-content.ts选择器为ng-template[ngMenuContent]自身不声明任何输入输出而是通过宿主指令DeferredContent来自src/aria/private获得内容延迟渲染能力div ngMenu #myMenungMenu ng-template ngMenuContent div ngMenuItem valueLazy Item 1Lazy Item 1/div div ngMenuItem valueLazy Item 2Lazy Item 2/div /ng-template /div包裹在ng-template中的菜单项只有在菜单首次打开时才会真正渲染进 DOM配合Menu上的preserveContent输入经DeferredContentAware宿主指令透传决定关闭后是否保留已渲染内容。这一机制对包含重资源内容或大量菜单项的复杂菜单尤其有用可显著降低初始渲染成本。八、测试 HarnessMenuHarness 与 MenuItemHarnessangular/aria_menu/testing入口提供了两个基于angular/cdk/testing的组件 Harness源码见 src/aria/menu/testing/menu-harness.tsAPI 基线见 goldens/aria/menu/testing/index.api.md用于在单元测试与 E2E 测试中以语义化方式驱动菜单而不是直接操作原生 DOM。8.1 MenuHarness宿主选择器[ngMenu], [ngMenuBar]过滤器MenuHarnessFilters extends BaseHarnessFilters支持triggerText?: string | RegExp可按触发器文本精确定位菜单方法isOpen(): Promiseboolean— 菜单是否打开菜单栏恒为true普通菜单读取data-visible属性isMenuBar(): Promiseboolean— 是否为菜单栏open()/close()— 通过定位aria-controls反向关联的触发器并点击来开关菜单getItems(filters?: MenuItemHarnessFilters): PromiseMenuItemHarness[]— 查询内部菜单项。其中_getTrigger()的实现思路值得一提它先读取菜单宿主的id再用[aria-controlsid]在文档根上反查触发器menu-harness.ts完全依赖本包自动生成的 ARIA 关联无需测试者额外传选择器。8.2 MenuItemHarness宿主选择器[ngMenuItem]过滤器MenuItemHarnessFilters extends BaseHarnessFilters支持text?: string | RegExp、disabled?: boolean、expanded?: boolean方法getText(): Promisestring— 获取项文本click(): Promisevoid— 点击触发动作或切换子菜单isDisabled()/isExpanded()/isFocused()/hasSubmenu()— 读取aria-disabled、aria-expanded、焦点状态、aria-haspopup/aria-controlsgetSubmenu(): PromiseMenuHarness | null— 通过aria-controls解析并返回嵌套子菜单的 Harness。8.3 测试写法示例结合 menu-harness.spec.ts 的测试模式典型用例形如const menu await loader.getHarness(MenuHarness.with({triggerText: Options})); expect(await menu.isOpen()).toBe(false); await menu.open(); const items await menu.getItems({text: Edit}); expect(await items[0].isDisabled()).toBe(false); await items[0].click();九、底层设计Pattern 架构与 Signal 化从 API 报告与源码可以观察到一个贯穿始终的设计骨架这部分属于对源码结构的推断供深入阅读参考Pattern 模式每个指令内部都持有一个对应名称的_pattern实例——MenuPattern、MenuItemPattern、MenuTriggerPattern、MenuBarPattern定义于 src/aria/private。指令的宿主事件绑定全部转发给 PatternUI 行为键盘导航、焦点管理、typeahead、子菜单展开时机与 Angular 指令解耦便于独立测试与复用。全信号化输入输出所有输入均为InputSignal布尔类使用booleanAttribute转换状态active、expanded、hasPopup、visible、tabIndex均为computed()派生信号parent是WritableSignalsearchTerm/value使用ModelSignal支持双向绑定。这与 Angular 新信号体系深度契合任何输入变化都会经由信号图自动传播到 DOM 绑定。DOM 观察与动态集合SortedCollectionsrc/aria/private配合afterNextRender观察菜单项 DOM 变化支持*ngFor动态增删项时保持键盘导航顺序正确menu.spec.ts中的动态打乱用例menu.spec.ts正是对该能力的回归验证。ARIA 自动化aria-controls、aria-haspopup、aria-expanded、aria-disabled等属性全部由指令根据内部状态自动生成开发模式下的reportViolations还会在控制台提示结构错误如孤立ngMenuItem把无障碍语义的正确性内置到框架层。十、快速上手清单要在你自己的 Angular 应用中使用angular/aria_menu安装angular/aria包src/aria目录即其源码引入Menu、MenuItem、MenuTrigger、MenuBar、MenuContent指令均可从包的公共入口导入见 src/aria/menu/public-api.ts用ngMenuTriggerngMenungMenuItem三件套搭建下拉菜单用[submenu]实现多级嵌套用ngMenuBar承载常驻顶层菜单通过(itemSelected)接收选中值通过[(value)]仅MenuBar管理多选状态需要延迟渲染时把菜单项包进ng-template ngMenuContent测试中引入angular/aria_menu/testing用MenuHarness/MenuItemHarness以语义化方式驱动菜单并断言其 ARIA 状态。以上所有 API 的名称、类型、默认值与行为均可在 goldens/aria/menu/index.api.md 与 src/aria/menu 的源码中逐一核对。【免费下载链接】componentsComponent infrastructure and Material Design components for Angular项目地址: https://gitcode.com/GitHub_Trending/co/components创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Seata AT模式:微服务分布式事务解决方案详解 2026/9/11 22:22:08

Seata AT模式:微服务分布式事务解决方案详解

1. 分布式事务的核心挑战与Seata的定位在微服务架构中,最让人头疼的问题之一就是如何保证跨服务的数据一致性。想象一下电商系统中的经典场景:用户下单后需要同时扣减库存和创建订单——这两个操作分别属于库存服务和订单服务。如果库存扣减成功但订单创…

阅读更多 →
C++11枚举类:类型安全与高级应用实践 2026/9/11 22:22:08

C++11枚举类:类型安全与高级应用实践

1. 枚举类基础回顾与类型安全优势在C11标准引入枚举类(enum class)之前,传统C风格枚举存在几个显著问题:枚举常量直接暴露在外部作用域、隐式转换为整型、无法指定底层存储类型。这些问题在大型项目中经常导致命名冲突和类型安全问题。枚举类通过引入强类…

阅读更多 →
SpringBoot+Vue记账系统实战:全栈开发与数据一致性保障 2026/9/11 22:22:08

SpringBoot+Vue记账系统实战:全栈开发与数据一致性保障

简介:这是一套面向Java初学者与毕业设计学生的全栈记账系统实战项目,基于SpringBootVue技术栈构建,聚焦大学生日常消费管理场景,助力课程设计、期末大作业及毕业设计快速落地。资源包共374个文件,涵盖85个核心Java后端…

阅读更多 →
用 /market-scan 一次跑完四大战略框架:pm-skills 宏观环境扫描命令实战指南 2026/9/11 22:22:08

用 /market-scan 一次跑完四大战略框架:pm-skills 宏观环境扫描命令实战指南

用 /market-scan 一次跑完四大战略框架:pm-skills 宏观环境扫描命令实战指南 【免费下载链接】pm-skills PM Skills Marketplace: 100 agentic skills, commands, and plugins — from discovery to strategy, execution, launch, and growth. 项目地址: https://…

阅读更多 →
Vibe-Trading 数据接入实战:Tushare AH 股比价接口(stk_ah_comparison)从调用到策略应用全解析 2026/9/11 22:22:08

Vibe-Trading 数据接入实战:Tushare AH 股比价接口(stk_ah_comparison)从调用到策略应用全解析

Vibe-Trading 数据接入实战:Tushare AH 股比价接口(stk_ah_comparison)从调用到策略应用全解析 【免费下载链接】Vibe-Trading "Vibe-Trading: Your Personal Trading Agent" 项目地址: https://gitcode.com/GitHub_Trending/vi/…

阅读更多 →
圆上弦交点最大化算法与应用解析 2026/9/11 22:19:07

圆上弦交点最大化算法与应用解析

1. 项目概述:CF1552C Maximize the Intersections这是一道来自Codeforces竞赛的经典组合数学题目,主要考察选手对圆上弦交点最大化的理解和计算能力。题目要求在一个圆周上放置2n个点,其中k对点已经预先连接成弦,我们需要在剩余的…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞