【问题标题】:Is there any knockout plugin for showing a nested context menu?是否有任何用于显示嵌套上下文菜单的淘汰插件?
【发布时间】:2015-06-05 21:55:26
【问题描述】:

有没有用于显示嵌套上下文菜单的剔除插件?

我的具体需要是为列表项显示一个上下文菜单,它有一个“SendTo”菜单项,并且必须在运行时设置可能的子项。

【问题讨论】:

  • 请注意,要求我们推荐或查找书籍、工具、软件库、教程或其他场外资源的问题对于 Stack Overflow 来说是无关紧要的,因为它们往往会吸引固执己见的答案和垃圾邮件.相反,请描述问题以及迄今为止为解决该问题所做的工作。

标签: jquery-ui knockout.js


【解决方案1】:

由于明显缺乏合适的插件,我选择了更直接的 Knockout 方法。我确信代码可以更优雅地打包在自定义绑定中,但如果有人需要类似的东西,这是我想出的解决方案。在我的情况下,每次打开菜单时都会构建菜单,因为它在我的用例中是有意义的。我确信代码可以很容易地定制到其他一些场景。

所以...标记:
<li data-bind="event: { contextmenu: $root.showSendToMenu }/> 用于显示弹出菜单,用于右键单击项目。 以及菜单本身的标记:

@*The send to popup menu*@
<ul class="context-menu" data-bind="visible:contextMenu.activeElement, style:{left:contextMenu.left, top:contextMenu.top}, template: { name: 'menu-item-template', foreach: contextMenu.items }, event: { mouseleave: contextMenu.contextMouseLeave }"></ul>

@*Template for a menu item*@
<script type="text/html" id="menu-item-template">
    <li>
        <!-- ko if: children -->
        <span data-bind="text:text"></span>
        <ul data-bind="template: { name: 'menu-item-template', foreach: children }"></ul>
        <!-- /ko -->
        <!-- ko if: !children -->
        <a href="#" data-bind="text:text, click:$root.onContextClick"></a>
        <!-- /ko -->
    </li>
</script>

在 viewModel 中,我有以下代码(TypeScript):

contextMenu = { activeElement: ko.observable(null), left: ko.observable('0px'), top: ko.observable('200px'), items: ko.observableArray(<MenuItem[]>[]), contextMouseLeave : () => { this.contextMenu.activeElement(null); } };

    showSendToMenu = (item, event) => {

        //Set menu position
        this.contextMenu.left(event.pageX + 'px');
        this.contextMenu.top(event.pageY + 'px');

        //Build the menu
        var lines = [];
        for (var i = 0; i < this.prodLines().length; i++) {
            var line = this.prodLines()[i];

            if (line.lists().length > 0) {
                var lists = [];
                for (var j = 0; j < line.lists().length; j++) {
                    var list = line.lists()[j];
                    lists.push(new MenuItem(list.name(), null, list));
                }
                lines.push(new MenuItem(line.name + "->", lists, line));
            }
        }

        var items = [new MenuItem("SendTo ->", lines)];

        //Set the menu
        this.contextMenu.items(items);
        this.contextMenu.activeElement(item);
    }


    onContextClick = (menuItem: MenuItem) => {
        var sendToList = menuItem.tag;
        var item = this.contextMenu.activeElement();
        this.dropToList(item, sendToList);
        //Hide the menu
        this.contextMenu.activeElement(null);
    }

最后,我使用这段 css 使菜单的行为类似于菜单:

.context-menu {
  position: absolute;
  padding: 0;
  margin: 0;
  z-index: 1030;
  background-color: #dddddd;
  box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.3);
  min-width:100px;
  border: 1px solid gray;
  text-decoration:none;
}
.context-menu ul {
  position: absolute;
  z-index: 1031;
  line-height: 1.6;
  padding: 0;
  margin: 0;
  box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.3);
  display:none;
  left:98px;
  min-width:100px;
  top:-1px;
  background-color:#dddddd;
  border: 1px solid gray;
  text-decoration:none;
}

.context-menu li {
  position:relative;
}

.context-menu li:hover > ul {
  display:block;
}

.context-menu li {
  padding: 4px 20px;
  margin: 0;
  list-style-type: none;
  cursor: pointer;
  white-space: nowrap;
  color: #333333;
}
.context-menu ul > li:hover {
  background-color: white;
  text-decoration:underline;
}

我希望这会对某人有所帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-16
    • 1970-01-01
    相关资源
    最近更新 更多