关于 syncfusion-angular-context-menu
面向 Angular 开发者的 Syncfusion ContextMenu 实现技能,用于构建右键或触摸长按菜单。支持嵌套结构、动态菜单项、模板和事件处理。
主要功能
- 01右键与触摸长按菜单
- 02嵌套菜单项
- 03动态增删与启用菜单项
- 04数组或对象数据绑定
- 05自定义模板与动画
- 06键盘交互与事件处理
适用场景
- 01为编辑区域提供上下文操作
- 02按用户权限显示不同菜单项
- 03从菜单项打开对话框或执行操作
- 04为大型菜单启用滚动
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ syncfusion/ angular-ui-components-skills --skill syncfusion-angular-context-menu安装后在 Claude Code 中输入/syncfusion-angular-context-menu确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/data-binding.mdgetting-started.mdinteraction-and-events.mdmenu-items-management.mdstyling-and-customization.mdtemplates-and-advanced.md详细介绍
实现 Syncfusion Angular ContextMenu
ContextMenu 是一种图形用户界面,可在用户右键单击或按住触摸时显示。它提供可根据上下文显示的菜单,并支持嵌套项、动态更新、动画、自定义模板和全面的事件处理。本技能将指导你在 Angular 应用中实现、配置和自定义上下文菜单。
何时使用本技能
适用场景:
- 需要创建右键单击或按住触摸时显示的上下文菜单
- 动态管理菜单项(添加、移除、启用、禁用)
- 处理菜单项点击事件和操作
- 根据菜单选择打开对话框或导航
- 使用动画、图标或主题自定义菜单外观
- 根据上下文或用户权限显示或隐藏菜单项
- 从数据源绑定菜单项
- 创建复杂的菜单模板或嵌套结构
- 实现支持滚动的响应式菜单
- 添加键盘快捷键或无障碍功能
组件概述
ContextMenu 组件支持直观的右键交互界面,提供:
- ✅ 动态管理菜单项(添加/移除/启用/禁用)
- ✅ 多级嵌套菜单
- ✅ 从数组或对象绑定数据
- ✅ 可自定义动画(FadeIn、SlideDown、ZoomIn、None)
- ✅ 支持富内容的模板(图标、HTML、表格)
- ✅ 事件处理(点击、打开、关闭)
- ✅ 图标和 URL 导航
- ✅ 支持大量菜单项的可滚动菜单
- ✅ 支持键盘操作的无障碍功能
文档与导航指南
开始使用
📄 阅读: references/getting-started.md
- 安装软件包和依赖项
- 设置 Angular 环境(独立架构)
- 创建第一个 ContextMenu
- 配置目标元素
- 菜单项基本结构
菜单项管理
📄 阅读: references/menu-items-management.md
- 动态添加菜单项(insertBefore、insertAfter)
- 移除菜单项(removeItems 方法)
- 启用和禁用菜单项(enableItems)
- 显示和隐藏菜单项(showItems、hideItems)
- 动态的上下文感知菜单
- 多级嵌套菜单
数据绑定
📄 阅读: references/data-binding.md
- 从数据源填充菜单项
- MenuItemModel 结构和属性
- 父子菜单项关系
- 用于设置菜单项格式的 beforeItemRender 事件
- 动态数据更新
交互与事件
📄 阅读: references/interaction-and-events.md
- 菜单项点击处理程序(select 事件)
- 点击打开子菜单(showItemOnClick)
- 以编程方式打开和关闭菜单的方法
- 使用坐标设置菜单位置
- 选择菜单项时打开对话框
- MenuEventArgs 和事件属性
样式与自定义
📄 阅读: references/styling-and-customization.md
- 动画设置和效果(FadeIn、SlideDown、ZoomIn、None)
- CSS 自定义和类定位
- 使用 iconCss 属性设置图标样式
- URL 导航和外部链接
- 可滚动菜单(enableScrolling)
- 响应式设计和 Theme Studio
模板与高级功能
📄 阅读: references/templates-and-advanced.md
- 自定义菜单项模板(itemTemplate)
- 使用 HTML 和表格呈现富内容
- 字符下划线和格式设置
- 分隔项和分组
- 无障碍功能和键盘导航
- 高级模板模式
快速入门示例
import { Component } from '@angular/core';
import { ContextMenuModule } from '@syncfusion/ej2-angular-navigations';
import { MenuItemModel } from '@syncfusion/ej2-navigations';
@Component({
selector: 'app-root',
standalone: true,
imports: [ContextMenuModule],
template: `
<div class="e-section-control">
<div id="target">Right click / Touch hold to open the ContextMenu</div>
<ejs-contextmenu
id='contextmenu'
target='#target'
[items]='menuItems'>
</ejs-contextmenu>
</div>
`
})
export class AppComponent {
public menuItems: MenuItemModel[] = [
{ text: 'Cut', iconCss: 'e-cm-icons e-cut' },
{ text: 'Copy', iconCss: 'e-cm-icons e-copy' },
{ text: 'Paste', iconCss: 'e-cm-icons e-paste' },
{ separator: true },
{
text: 'View',
items: [
{ text: 'Large icons' },
{ text: 'Small icons' }
]
}
];
}
常见模式
模式 1:动态管理菜单项
// Add items after 'Refresh'
this.contextmenu.insertAfter([{ text: 'Sort By' }], 'Refresh');
// Remove 'Paste' item
this.contextmenu.removeItems(['Paste']);
// Disable 'Edit' item
this.contextmenu.enableItems(['Edit'], false);
模式 2:上下文感知菜单
beforeOpen(args: BeforeOpenCloseMenuEventArgs) {
if ((args.event.target as HTMLElement).id === 'editor') {
this.contextmenu.showItems(['Add', 'Edit', 'Delete']);
this.contextmenu.hideItems(['Cut', 'Copy', 'Paste']);
}
}
模式 3:菜单项点击处理程序
itemSelect(args: MenuEventArgs): void {
if (args.item.text === 'Save As...') {
this.dialogComponent.show();
}
}
模式 4:动画配置
public animationSettings = {
effect: 'FadeIn',
duration: 400,
easing: 'ease'
};
完整 API 参考
组件属性
核心配置属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
target | string | '' | 必填。 指定要打开 ContextMenu 的目标元素选择器。 |
items | MenuItemModel[] | [] | 指定将作为 ContextMenu 呈现的菜单项及其属性。 |
showItemOnClick | boolean | false | 指定点击时是否显示子菜单。设为 true 时,子菜单仅在鼠标点击后打开。 |
filter | string | '' | 指定目标内部元素的筛选选择器,右键菜单将在这些元素上打开。 |
hoverDelay | number | 0 | 如果将 hoverDelay 设为特定数值,菜单将在该时间段(以毫秒为单位)后打开。 |
样式与外观属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
animationSettings | MenuAnimationSettingsModel | { duration: 400, easing: 'ease', effect: 'SlideDown' } | 指定子菜单打开/关闭时的动画设置。请参阅动画设置部分。 |
cssClass | string | '' | 在菜单包装器中定义一个或多个以空格分隔的类,用于自定义样式。 |
enableRtl | boolean | false | 启用或禁用以从右向左的方向渲染组件。 |
数据与行为属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
itemTemplate | string | Function | null | 此属性允许为 ContextMenu 中的菜单项定义自定义模板。可以是字符串选择器或模板函数。 |
locale | string | '' | 覆盖此组件的全局区域性和本地化值。默认全局区域性为 'en-US'。 |
enableScrolling | boolean | false | 指定是否启用 ContextMenu 中的滚动选项。 |
安全与持久化属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enableHtmlSanitizer | boolean | true | 指定是否启用不受信任 HTML 值的渲染。设为 true 时,组件会在渲染前清理任何疑似不受信任的字符串和脚本。仅当完全信任 HTML 来源时才设为 false。 |
enablePersistence | boolean | false | 启用或禁用在页面重新加载期间保留组件状态。启用后,菜单状态会保存到 localStorage 中。 |
属性示例 - 基本配置
简要示例:
@Component({
selector: 'app-context-menu',
template: `
<div id="target">Right click here</div>
<ejs-contextmenu
target='#target'
[items]='items'
[animationSettings]='animSettings'
cssClass='custom-menu'>
</ejs-contextmenu>
`
})
export class ContextMenuComponent {
items: MenuItemModel[] = [
{ text: 'Edit' },
{ text: 'Delete' }
];
animSettings = {
duration: 300,
effect: 'FadeIn',
easing: 'ease-out'
};
}
完整工作示例:
import { Component, ViewChild } from '@angular/core';
import { ContextMenuComponent } from '@syncfusion/ej2-angular-navigations';
import { MenuItemModel } from '@syncfusion/ej2-navigations';
@Component({
selector: 'app-context-menu-config',
standalone: true,
imports: [ContextMenuModule],
template: `
<div class="container">
<h3>Advanced Configuration Example</h3>
<div id="configTarget" class="target-box">
Right click or touch hold to open menu
</div>
<ejs-contextmenu
#contextMenu
id='contextMenu'
target='#configTarget'
[items]='menuItems'
[animationSettings]='animationSettings'
cssClass='modern-menu'
[showItemOnClick]='true'
[enableScrolling]='true'
[hoverDelay]='300'
[enableHtmlSanitizer]='true'
[enablePersistence]='true'
locale='en-US'>
</ejs-contextmenu>
</div>
`,
styles: [`
.target-box {
width: 300px;
height: 200px;
border: 2px dashed #ccc;
display: flex;
align-items: center;
justify-content: center;
background: #f5f5f5;
cursor: context-menu;
}
`]
})
export class AdvancedContextMenuComponent {
@ViewChild('contextMenu') contextMenu!: ContextMenuComponent;
menuItems: MenuItemModel[] = [
{ text: 'Edit', iconCss: 'e-cm-icons e-edit', id: 'edit' },
{ text: 'Delete', iconCss: 'e-cm-icons e-delete', id: 'delete' },
{ separator: true },
{ text: 'More', id: 'more' }
];
animationSettings = {
effect: 'FadeIn' as any,
duration: 400,
easing: 'ease-in-out'
};
}
菜单项属性(MenuItemModel)
MenuItemModel 定义了每个菜单项的结构。items 数组中的每个项都遵循此模型:
| 属性 | 类型 | 可选 | 说明 |
|---|---|---|---|
text | string | 否 | 必填。 指定菜单项的文本。这是显示给用户的标签。 |
id | string | 是 | 指定菜单项的 ID。可用于在 enableItems()、removeItems() 等方法中标识菜单项。 |
items | MenuItemModel[] | 是 | 指定子菜单项,即 MenuItem 模型数组。用于创建嵌套/分层菜单。 |
separator | boolean | 是 | 指定菜单项之间是否显示分隔符。分隔符是用于对菜单项分组的水平线或垂直线。设为 true 可创建视觉分隔线。 |
iconCss | string | 是 | 定义一个或多个以空格分隔的类,用于为菜单项添加图标。菜单项可以包含字体图标和精灵图。示例:iconCss: 'e-icons e-edit'。 |
url | string | 是 | 指定菜单项的 URL,并创建指向所提供 URL 的锚点链接。点击后会导航至此 URL。 |
htmlAttributes | Record<string, any> | 是 | 指定 htmlAttributes 属性,以支持为菜单项添加自定义属性。示例:{ 'data-info': 'value', 'title': 'My Tooltip' }。 |
菜单项示例 - 基本用法
简要示例:
items: MenuItemModel[] = [
{ text: 'Cut', id: 'cut', iconCss: 'e-icons e-cut' },
{ text: 'Copy', id: 'copy', iconCss: 'e-icons e-copy' },
{ text: 'Paste', id: 'paste', iconCss: 'e-icons e-paste' },
{ separator: true },
{ text: 'Delete', id: 'delete', iconCss: 'e-icons e-delete' }
];
完整示例 - 复杂的 MenuItemModel:
@Component({
selector: 'app-menu-items-config',
standalone: true,
imports: [ContextMenuModule],
template: `
<div id="target">Right click for advanced menu</div>
<ejs-contextmenu target='#target' [items]='menuItems'></ejs-contextmenu>
`
})
export class MenuItemsComponent {
menuItems: MenuItemModel[] = [
// Item with icon
{
text: 'Edit',
id: 'edit-item',
iconCss: 'e-icons e-edit',
htmlAttributes: {
'data-action': 'edit',
'title': 'Edit selected item'
}
},
// Item with submenu
{
text: 'Format',
id: 'format',
iconCss: 'e-icons e-palette',
items: [
{ text: 'Bold', id: 'bold' },
{ text: 'Italic', id: 'italic' },
{ text: 'Underline', id: 'underline' }
]
},
// Navigation item with URL
{
text: 'Visit Website',
id: 'website',
iconCss: 'e-icons e-export',
url: 'https://example.com',
htmlAttributes: { 'target': '_blank' }
},
// Separator
{ separator: true },
// Item with nested submenu
{
text: 'Advanced',
id: 'advanced',
items: [
{
text: 'Settings',
id: 'settings',
items: [
{ text: 'General', id: 'general' },
{ text: 'Advanced', id: 'adv' }
]
},
{ text: 'Help', id: 'help', url: 'https://help.example.com' }
]
}
];
}
组件方法
方法:enableItems
签名:
enableItems(items: string[], enable?: boolean, isUniqueId?: boolean): void
| 参数 | 类型 | 可选 | 说明 |
|---|---|---|---|
items | string[] | 否 | 需要启用/禁用的菜单项文本或 ID 数组。 |
enable | boolean | 是,默认值:true | 设为 true 可启用菜单项;设为 false 可禁用菜单项。 |
isUniqueId | boolean | 是,默认值:false | 如果 items 数组包含的是唯一 ID 而非文本,则设为 true。 |
返回值: void
简要示例:
// Disable 'Delete' item by text
this.contextMenu.enableItems(['Delete'], false);
// Enable items by id
this.contextMenu.enableItems(['edit-item', 'copy-item'], true, true);
完整示例:
@Component({
selector: 'app-enable-items',
template: `
<button (click)="disableDelete()">Disable Delete</button>
<button (click)="enableAll()">Enable All</button>
<div id="target">Right click here</div>
<ejs-contextmenu #cm target='#target' [items]='items'></ejs-contextmenu>
`
})
export class EnableItemsComponent {
@ViewChild('cm') contextMenu!: ContextMenuComponent;
items: MenuItemModel[] = [
{ text: 'Edit', id: 'edit' },
{ text: 'Delete', id: 'delete' },
{ text: 'Copy', id: 'copy' }
];
disableDelete() {
this.contextMenu.enableItems(['Delete'], false);
}
enableAll() {
this.contextMenu.enableItems(['Edit', 'Delete', 'Copy'], true);
}
}
方法:insertAfter
签名:
insertAfter(items: MenuItemModel[], text: string, isUniqueId?: boolean): void
| 参数 | 类型 | 可选 | 说明 |
|---|---|---|---|
items | MenuItemModel[] | 否 | 需要插入的 MenuItemModel 数组。 |
text | string | 否 | 要在其后插入元素的菜单项文本。如果 isUniqueId 为 true,则此值为唯一 ID。 |
isUniqueId | boolean | 是,默认值:false | 如果 text 是唯一 ID 而非显示文本,则设为 true。 |
返回值: void
简要示例:
// Insert item after 'Edit'
this.contextMenu.insertAfter([{ text: 'Save' }], 'Edit');
// Insert after item with specific id
this.contextMenu.insertAfter([{ text: 'New', id: 'new-item' }], 'edit-item', true);
完整示例:
@Component({
selector: 'app-insert-after',
template: `
<button (click)="addAfterEdit()">Add Item After Edit</button>
<div id="target">Right click here</div>
<ejs-contextmenu #cm target='#target' [items]='items'></ejs-contextmenu>
`
})
export class InsertAfterComponent {
@ViewChild('cm') contextMenu!: ContextMenuComponent;
items: MenuItemModel[] = [
{ text: 'Edit', id: 'edit' },
{ text: 'Delete', id: 'delete' }
];
addAfterEdit() {
this.contextMenu.insertAfter(
[
{ text: 'Copy', id: 'copy' },
{ text: 'Paste', id: 'paste' }
],
'Edit'
);
}
}
方法:insertBefore
签名:
insertBefore(items: MenuItemModel[], text: string, isUniqueId?: boolean): void
| 参数 | 类型 | 可选 | 说明 |
|---|---|---|---|
items | MenuItemModel[] | 否 | 需要插入的 MenuItemModel 数组。 |
text | string | 否 | 要在其前插入元素的菜单项文本。如果 isUniqueId 为 true,则此值为唯一 ID。 |
isUniqueId | boolean | 是,默认值:false | 如果 text 是唯一 ID 而非显示文本,则设为 true。 |
返回值: void
简要示例:
this.contextMenu.insertBefore([{ text: 'Undo' }], 'Edit');
方法:removeItems
签名:
removeItems(items: string[], isUniqueId?: boolean): void
| 参数 | 类型 | 可选 | 说明 |
|---|---|---|---|
items | string[] | 否 | 需要移除的菜单项文本或 ID 数组。 |
isUniqueId | boolean | 是,默认值:false | 如果 items 数组包含的是唯一 ID 而非文本,则设为 true。 |
返回值: void
简要示例:
this.contextMenu.removeItems(['Delete', 'Copy']);
方法:hideItems
签名:
hideItems(items: string[], isUniqueId?: boolean): void
| 参数 | 类型 | 可选 | 描述 |
|---|---|---|---|
items | string[] | 否 | 需要隐藏的项目文本或 ID 数组。 |
isUniqueId | boolean | 是,默认值:false | 如果 items 数组包含唯一 ID 而非文本,则设为 true。 |
返回值: void
简要示例:
this.contextMenu.hideItems(['AdminOnly'], true);
方法:showItems
签名:
showItems(items: string[], isUniqueId?: boolean): void
| 参数 | 类型 | 可选 | 描述 |
|---|---|---|---|
items | string[] | 否 | 需要显示的项目文本或 ID 数组。 |
isUniqueId | boolean | 是,默认值:false | 如果 items 数组包含唯一 ID 而非文本,则设为 true。 |
返回值: void
简要示例:
this.contextMenu.showItems(['AdminOnly'], true);
方法:getItemIndex
签名:
getItemIndex(item: MenuItem | string, isUniqueId?: boolean): number[]
| 参数 | 类型 | 可选 | 描述 |
|---|---|---|---|
item | MenuItem | string | 否 | 要获取索引的 MenuItem 对象或 ID/文本。 |
isUniqueId | boolean | 是,默认值:false | 如果 item 是唯一 ID 而非文本,则设为 true。 |
返回值: number[] - 表示该项目在菜单层级中位置的索引数组。
简要示例:
// Get index by text
const index = this.contextMenu.getItemIndex('Edit'); // [0] for first item
// Get index by id
const index = this.contextMenu.getItemIndex('edit-item', true); // [0]
// For nested items
const index = this.contextMenu.getItemIndex('Bold', true); // [1, 0] for Format > Bold
完整示例:
@Component({
selector: 'app-get-index',
template: `
<button (click)="findItem()">Find Item Index</button>
<div>Index: {{ itemIndex }}</div>
<div id="target">Right click here</div>
<ejs-contextmenu #cm target='#target' [items]='items'></ejs-contextmenu>
`
})
export class GetIndexComponent {
@ViewChild('cm') contextMenu!: ContextMenuComponent;
itemIndex: any = null;
items: MenuItemModel[] = [
{ text: 'Edit', id: 'edit' },
{
text: 'Format',
id: 'format',
items: [
{ text: 'Bold', id: 'bold' },
{ text: 'Italic', id: 'italic' }
]
}
];
findItem() {
this.itemIndex = this.contextMenu.getItemIndex('Bold', true);
console.log('Item index:', this.itemIndex); // [1, 0]
}
}
方法:setItem
签名:
setItem(item: MenuItem, id?: string, isUniqueId?: boolean): void
| 参数 | 类型 | 可选 | 描述 |
|---|---|---|---|
item | MenuItem | 否 | 包含已更新属性的 MenuItem 对象。 |
id | string | 是 | 要更新的项目的 ID 或文本。如果未提供,则更新作为第一个参数传入的项目。 |
isUniqueId | boolean | 是,默认值:false | 如果 id 是唯一 ID 而非文本,则设为 true。 |
返回值: void
简要示例:
// Update item by text
this.contextMenu.setItem({ text: 'Edit Document' }, 'Edit');
// Update item by id
this.contextMenu.setItem(
{ text: 'Remove', iconCss: 'e-icons e-delete' },
'delete-item',
true
);
方法:open
签名:
open(top: number, left: number, target?: HTMLElement): void
| 参数 | 类型 | 可选 | 描述 |
|---|---|---|---|
top | number | 否 | 用于指定 ContextMenu 的垂直位置(以像素为单位的 Y 坐标)。 |
left | number | 否 | 用于指定 ContextMenu 的水平位置(以像素为单位的 X 坐标)。 |
target | HTMLElement | 是 | 根据指定的目标元素计算 ContextMenu 的 z-index。 |
返回值: void
简要示例:
// Open at mouse position
this.contextMenu.open(event.clientY, event.clientX);
// Open at specific coordinates
this.contextMenu.open(200, 300);
// Open relative to target element
this.contextMenu.open(100, 150, document.getElementById('target'));
方法:close
签名:
close(): void
| 参数 | - | - | - |
|---|
返回值: void
简要示例:
// Close the open ContextMenu
this.contextMenu.close();
方法:destroy
签名:
destroy(): void
| 参数 | - | - | - |
|---|
返回值: void
简要示例:
// Completely destroy the component and cleanup resources
this.contextMenu.destroy();
完整示例 - 在组件销毁时销毁:
import { Component, ViewChild, OnDestroy } from '@angular/core';
import { ContextMenuComponent } from '@syncfusion/ej2-angular-navigations';
@Component({
selector: 'app-destroy-example',
template: `
<button (click)="destroyMenu()">Destroy Menu</button>
<div id="target">Right click here</div>
<ejs-contextmenu #cm target='#target' [items]='items'></ejs-contextmenu>
`
})
export class DestroyExampleComponent implements OnDestroy {
@ViewChild('cm') contextMenu!: ContextMenuComponent;
items: MenuItemModel[] = [{ text: 'Item 1' }];
destroyMenu() {
if (this.contextMenu) {
this.contextMenu.destroy();
console.log('Menu destroyed');
}
}
ngOnDestroy() {
// Cleanup when component is destroyed
if (this.contextMenu) {
this.contextMenu.destroy();
}
}
}
动画设置(MenuAnimationSettingsModel)
配置菜单项打开/关闭时的动画效果:
| 属性 | 类型 | 默认值 | 描述 |
|---|---|---|---|
duration | number | 400 | 指定菜单变换/动画的持续时间(以毫秒为单位)。示例:300 表示动画持续 300ms。 |
easing | string | 'ease' | 指定变换时应用的缓动效果。示例:'ease'、'ease-in'、'ease-out'、'ease-in-out'、'linear'、'cubic-bezier(0.25, 0.1, 0.25, 1)'。 |
effect | MenuEffect | 'SlideDown' | 指定子菜单变换时显示的效果。选项:'None' | 'SlideDown' | 'ZoomIn' | 'FadeIn'。 |
效果选项:
- None:指定子菜单变换时不应用动画效果。
- SlideDown:指定子菜单变换时应用向下滑动效果(默认)。
- ZoomIn:指定子菜单变换时应用放大效果。
- FadeIn:指定子菜单变换时应用淡入效果。
简要示例:
animationSettings = {
duration: 300,
effect: 'FadeIn' as any,
easing: 'ease-out'
};
完整示例:
@Component({
selector: 'app-animation-config',
template: `
<div id="target">Right click here</div>
<ejs-contextmenu
target='#target'
[items]='items'
[animationSettings]='animSettings'>
</ejs-contextmenu>
`
})
export class AnimationConfigComponent {
items: MenuItemModel[] = [
{ text: 'Option 1' },
{ text: 'Option 2' }
];
animSettings = {
effect: 'ZoomIn' as any,
duration: 200,
easing: 'ease-in-out'
};
}
组件事件
事件:beforeOpen
签名: (beforeOpen): EmitType<BeforeOpenCloseMenuEventArgs>
在菜单项打开前触发。可用于阻止菜单打开、根据上下文显示或隐藏菜单项,或在菜单显示前自定义菜单。
事件参数 - BeforeOpenCloseMenuEventArgs:
| 属性 | 类型 | 描述 |
|---|---|---|
name | string | 指定事件名称(值:'beforeOpen')。 |
简要示例:
onBeforeOpen(args: BeforeOpenCloseMenuEventArgs) {
console.log('Menu about to open');
}
完整示例:
@Component({
selector: 'app-before-open',
template: `
<div id="target">Right click to open</div>
<ejs-contextmenu
target='#target'
[items]='items'
(beforeOpen)='onBeforeOpen($event)'>
</ejs-contextmenu>
`
})
export class BeforeOpenComponent {
items: MenuItemModel[] = [{ text: 'Item 1' }];
onBeforeOpen(args: BeforeOpenCloseMenuEventArgs) {
console.log('Event:', args.name); // 'beforeOpen'
}
}
事件:beforeClose
签名: (beforeClose): EmitType<BeforeOpenCloseMenuEventArgs>
在菜单关闭前触发。可用于执行清理操作或阻止菜单关闭。
事件参数 - BeforeOpenCloseMenuEventArgs:
| 属性 | 类型 | 描述 |
|---|---|---|
name | string | 指定事件名称(值:'beforeClose')。 |
简要示例:
onBeforeClose(args: BeforeOpenCloseMenuEventArgs) {
console.log('Menu about to close');
}
事件:onOpen
签名: (onOpen): EmitType<OpenCloseMenuEventArgs>
在菜单项打开时触发。菜单打开并显示后,此事件会触发。
事件参数 - OpenCloseMenuEventArgs:
| 属性 | 类型 | 描述 |
|---|---|---|
name | string | 指定事件名称(值:'onOpen')。 |
简要示例:
onOpen(args: OpenCloseMenuEventArgs) {
console.log('Menu opened:', args.name);
}
完整示例:
@Component({
selector: 'app-open-event',
template: `
<div id="target">Right click here</div>
<ejs-contextmenu
target='#target'
[items]='items'
(onOpen)='onOpen($event)'
(onClose)='onClose($event)'>
</ejs-contextmenu>
<p>Status: {{ menuStatus }}</p>
`
})
export class OpenEventComponent {
items: MenuItemModel[] = [{ text: 'Item 1' }];
menuStatus = 'Closed';
onOpen(args: OpenCloseMenuEventArgs) {
this.menuStatus = 'Menu Opened - ' + args.name;
}
onClose(args: OpenCloseMenuEventArgs) {
this.menuStatus = 'Menu Closed - ' + args.name;
}
}
事件:onClose
签名: (onClose): EmitType<OpenCloseMenuEventArgs>
在菜单关闭时触发。菜单关闭且不再显示后,此事件会触发。
事件参数 - OpenCloseMenuEventArgs:
| 属性 | 类型 | 描述 |
|---|---|---|
name | string | 指定事件名称(值:'onClose')。 |
简要示例:
onClose(args: OpenCloseMenuEventArgs) {
console.log('Menu closed:', args.name);
}
事件:select
签名: (select): EmitType<MenuEventArgs>
选择菜单项时触发。可用于处理菜单项点击并执行相应操作。
事件参数 - MenuEventArgs:
| 属性 | 类型 | 描述 |
|---|---|---|
name | string | 指定事件名称(值:'select')。 |
简要示例:
onSelect(args: MenuEventArgs) {
console.log('Item selected:', args.name);
}
完整示例:
@Component({
selector: 'app-select-event',
template: `
<div id="target">Right click here</div>
<ejs-contextmenu
target='#target'
[items]='items'
(select)='onSelect($event)'>
</ejs-contextmenu>
<p>Selected: {{ selectedItem }}</p>
`
})
export class SelectEventComponent {
items: MenuItemModel[] = [
{ text: 'Edit', id: 'edit' },
{ text: 'Delete', id: 'delete' },
{ text: 'Copy', id: 'copy' }
];
selectedItem = 'None';
onSelect(args: MenuEventArgs) {
this.selectedItem = args.name;
console.log('Selected item event:', args.name);
}
}
事件:beforeItemRender
签名: (beforeItemRender): EmitType<MenuEventArgs>
渲染每个菜单项时触发。可用于在渲染前自定义每个菜单项的外观或行为。
事件参数 - MenuEventArgs:
| 属性 | 类型 | 描述 |
|---|---|---|
name | string | 指定事件名称(值:'beforeItemRender')。 |
简要示例:
onBeforeItemRender(args: MenuEventArgs) {
console.log('Rendering item:', args.name);
}
完整示例:
@Component({
selector: 'app-before-item-render',
template: `
<div id="target">Right click here</div>
<ejs-contextmenu
target='#target'
[items]='items'
(beforeItemRender)='onBeforeItemRender($event)'>
</ejs-contextmenu>
`
})
export class BeforeItemRenderComponent {
items: MenuItemModel[] = [
{ text: 'Edit', id: 'edit' },
{ text: 'Delete', id: 'delete' }
];
onBeforeItemRender(args: MenuEventArgs) {
console.log('Rendering:', args.name);
// Customize items before rendering
}
}
事件:created
签名: (created): EmitType<Event>
组件渲染完成后触发一次。可用于执行初始化后的设置。
事件参数:
| 属性 | 类型 | 描述 |
|---|---|---|
| - | Event | 标准 JavaScript Event 对象。 |
简要示例:
onCreated(event: Event) {
console.log('ContextMenu component created and ready');
}
主要属性和事件速查
| 属性/事件 | 用途 | 示例 |
|---|---|---|
items | 定义菜单结构 | items: MenuItemModel[] |
target | 触发菜单的元素 | target='#target' |
select | 菜单项点击 | (select)="onSelect($event)" |
beforeOpen | 菜单打开前 | (beforeOpen)="onBeforeOpen($event)" |
enableItems() | 切换菜单项的可用状态 | enableItems(['Edit'], false) |
insertAfter() | 在目标项后添加菜单项 | insertAfter([...], 'Refresh') |
hideItems() | 隐藏特定菜单项 | hideItems(['Cut', 'Copy']) |
animationSettings | 控制显示效果 | animationSettings: {...} |
常见用例
- 文件操作菜单 - 剪切、复制、粘贴、删除选项
- 内容编辑器菜单 - 格式、插入、链接、媒体选项
- 数据网格上下文菜单 - 编辑、删除、导出、筛选操作
- 导航菜单 - 页面或外部 URL 链接
- 基于权限的菜单 - 根据用户角色显示/隐藏菜单项
- 多语言菜单 - 根据翻译动态显示菜单项文本
- 确认对话框 - 执行操作前打开对话框
- 表格操作 - 管理数据表中的行/列
后续步骤
- 根据任务选择参考文件(入门指南、菜单管理、数据绑定、事件、样式或模板)
- 查看适用于具体用例的代码示例
- 将相关代码模式复制到项目中
- 根据应用场景自定义菜单项
- 使用不同的目标元素测试交互
需要帮助完成特定任务? 请参考上方相应的指南,并告诉我你正在实现哪项菜单功能。