jigsaw
jigsaw copied to clipboard
jigsaw comp game 2017 赛题:实现JigsawMenu组件
JigsawMenu组件
用于在界面上显示一个菜单。需要支持多级菜单。
难度系数1.3
Jigsaw已经有多个基础组件可以用于完成这个功能,完成这个赛题需要做的事情是恰当的组合这些功能,并提供良好的封装和API。需要熟熟练用Jigsaw的PopupService来控制弹出组件的位置等信息。
演示
交互方面请参考下面这个图上的效果(无视这个图上的css)。

使用我们为赛题专门准备的样式即可,如下

使用方法
应用有两种典型的使用方式:
- 上下文菜单。应用在ts代码中直接将菜单弹出在某个dom元素附近:
const menuData=[
{label: 'item1'},
{label: 'item2'},
{
label: 'item3', children: [
{label: 'item1'}, {label: 'item2'}
]
}
];
// 与PopupService的options相似
const options = {};
JigsawMenu.show(menuData, options);
- 导航菜单。应用可能直接将菜单当做一级导航栏显示出来:
<jigsaw-menu width="300px" [data]="menuData" (select)="onMenu(menuInfo)">
</jigsaw-menu>
详细需求
提示:Jigsaw已经实现的LIST组件,已经提供了非常接近菜单的功能了,具体可以看这个demo http://localhost:4200/#/list/list-full。
基本需求
输入属性(@Input)
要求这个组件具备如下的输入属性(@Input):
data: MenuData[]
其中 MenuData 的定义为:
{
label: string, // 菜单的主文本
description?: string, // 菜单的附加文本,未定义则不显示
icon?: string, // 菜单的图标,只要支持font-awesome和iconfont字符图标即可,未定义则不显示
children?: MenuData[] // 菜单的子节点
[prop: string]: any; // 应用自定义数据
}
关于children属性的进一步说明:
children属性有合法定义时,JigsawMenu组件需要显示右侧的小箭头,用于提示这个菜单项包含子菜单。- 鼠标滑到带有
children属性的菜单条目上的时候,需要调用JigsawMenu.show()弹出子级菜单,下面有对这个方法的详细说明。
输出属性(@Output)
要求提供如下输出属性(@Output)
select: EventEmitter<MenuData>当菜单被选中后,发出这个事件。
静态方法
要求提供如下的静态方法
show(menu: MenuData[], callback?: MenuCallback, popupOptions?: PopupOptions),这个方法用于弹出一个菜单。
各个参数的说明:
menu菜单的数据callback菜单被选中后的回调函数。其中MenuCallback的定义是(menuItem: MenuData) => voidpopupOptions弹出选项,PopupOptions在popup.service.ts有定义。
这个方法需要完成如下事情:
-
在弹出一个新的菜单的同时,需要关闭这个菜单的所有兄弟节点的子菜单。
-
调整菜单弹出的位置,当前菜单有可能弹出到可视范围以外,需要调整。比如这是win7的处理方式,可以参考

-
调整菜单垂直方向上的尺寸,极端情况下,某个菜单的内容特别多的时候,需要约束该菜单的最大高度,并显示滚动条。
其他
- 必须继承
AbstractJigsawComponent类 - 组件必须是行内块元素(inline-block)
- 组件的高度必须从当前皮肤环境中取得。可以参考已有组件的处理方式。
- 组件的宽度默认由内容撑开,但是如果应用给了width属性,则优先取该值作为组件的宽度。可以参考已有组件的处理方式。
FAQ
有任何问题(包括技术问题)可在这个issue下面留言,我们会一一解答。但是在询问之前,也请阅读一下本次比赛的FAQ,说不定那里有你想要的答案。
修改记录
赛题可能会随着比赛的进行而会对阐述不详细、错漏的部分做微调,我们每一次的修改都会在这个小节留下修改记录。因此请多多关注赛题的issue的变更记录,最好能够subscribe这个issue,这样有任何变更你都会收到通知。
- 2017/10/23 新建。