jigsaw icon indicating copy to clipboard operation
jigsaw copied to clipboard

jigsaw comp game 2017 赛题:实现JigsawMenu组件

Open rdkmaster opened this issue 8 years ago • 0 comments

JigsawMenu组件

用于在界面上显示一个菜单。需要支持多级菜单。

难度系数1.3

Jigsaw已经有多个基础组件可以用于完成这个功能,完成这个赛题需要做的事情是恰当的组合这些功能,并提供良好的封装和API。需要熟熟练用Jigsaw的PopupService来控制弹出组件的位置等信息。

演示

交互方面请参考下面这个图上的效果(无视这个图上的css)。

menu

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

menu-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) => void
  • popupOptions 弹出选项,PopupOptions在popup.service.ts有定义。

这个方法需要完成如下事情:

  • 在弹出一个新的菜单的同时,需要关闭这个菜单的所有兄弟节点的子菜单。

  • 调整菜单弹出的位置,当前菜单有可能弹出到可视范围以外,需要调整。比如这是win7的处理方式,可以参考 menu-pos

  • 调整菜单垂直方向上的尺寸,极端情况下,某个菜单的内容特别多的时候,需要约束该菜单的最大高度,并显示滚动条。

其他

  • 必须继承AbstractJigsawComponent
  • 组件必须是行内块元素(inline-block)
  • 组件的高度必须从当前皮肤环境中取得。可以参考已有组件的处理方式。
  • 组件的宽度默认由内容撑开,但是如果应用给了width属性,则优先取该值作为组件的宽度。可以参考已有组件的处理方式。

FAQ

有任何问题(包括技术问题)可在这个issue下面留言,我们会一一解答。但是在询问之前,也请阅读一下本次比赛的FAQ,说不定那里有你想要的答案。

修改记录

赛题可能会随着比赛的进行而会对阐述不详细、错漏的部分做微调,我们每一次的修改都会在这个小节留下修改记录。因此请多多关注赛题的issue的变更记录,最好能够subscribe这个issue,这样有任何变更你都会收到通知。

  • 2017/10/23 新建。

rdkmaster avatar Oct 27 '17 07:10 rdkmaster