如何绑定点击敲击中的上下文菜单,以便知道打开菜单的元素

时间:2013-09-29 18:08:58

标签: knockout.js contextmenu ko.observablearray

我使用foreach绑定到containerDiv绑定了一个observableArray。当新项目添加到可观察数组时,将在容器内创建新的div。

每个动态创建的div都可以点击(或点击),显示一种自制的上下文菜单,有几个选项,其中两个是“删除你刚刚点击的div”ahd“更改值你刚刚点击的那个div。“

contextmenu可以确定单击了哪个div,从而可以确定必须删除observableArray中的哪个索引或更改其值。但是上下文菜单如何将此信息传递回ViewModel?

对context-menu-option的click事件进行绑定只会告诉ViewModel单击了哪个菜单项;它没有透露信息的另一个重要部分,即负责打开上下文菜单的部分,必须编辑或删除的部分。

如何提供ViewModel a)必须发生的具体操作(菜单选项)和b)必须对其进行操作的可观察数组中的项目?

3 个答案:

答案 0 :(得分:0)

当您单击以首先显示上下文菜单时,将使用与div对应的模型元素调用您的处理程序。保存它,然后在从上下文菜单处理单击时使用它(必须来自该特定div)。

答案 1 :(得分:0)

someGlobalNamespace.ContextMenuVM = new function () {
    var self = this;
    var piece = {};
    var args = [];

    self.show = function (data, event) {
        piece = this;
        args = arguments;
        var posx = event.clientX + window.pageXOffset; //Left Position of Mouse Pointer
        var posy = event.clientY + window.pageYOffset; //Top Position of Mouse Pointer
        $('#ContextMenu').popup('open', {
            x:posx,
            y:posy,
            positionTo:'origin'
        });
    };

    self.clickHandler = function(fn){
        return function(){
            $('#ContextMenu').popup('close');
            fn.apply(piece, args);
        };
    };
}();

我在阅读其他答案后,解除了使用JQuery mobile进行显示/隐藏的问题。

通过缓存绑定到最初单击/ contextmenu'd元素的vm和函数参数的'this',可以使用Function.apply来委派点击。

这可能会导致原始点击处理程序检查事件的问题,并且看到它与点击事件不同,但可以通过一些小的重构来解决。

   <div id="ContextMenu" class="pieceContextMenu" data-role="popup" data-theme="c" data-dismissible="true">
        <div class="contextMenuItem CIicon Delete"    title="Delete"                data-bind="click: clickHandler(cms.canvasAreaVM.deleteUniformPiece)"><i style="cursor: pointer;" class="fa fa-times"></i><span class="contextMenuItemText">Delete</span></div>
        <div class="contextMenuItem CIicon Copy"      title="Clone"                 data-bind="click: clickHandler(cms.canvasAreaVM.copyFormPiece)"><i class="fa fa-copy"></i><span class="contextMenuItemText">Clone</span></div>
        <div class="contextMenuItem CIicon New"       title="Add new child"         data-bind="click: clickHandler(cms.addNewPieceVM.show)"><i class="fa fa-plus"></i><span class="contextMenuItemText">New</span></div>
        <div class="contextMenuItem CIicon NewParent" title="Add new parent"        data-bind="click: clickHandler(cms.canvasAreaVM.newParentFormPiece)"><i class="fa fa-plus-square"></i><span class="contextMenuItemText">New Parent</span></div>
        <div class="contextMenuItem CIicon CopyClip"  title="Copy to the clipboard" data-bind="click: clickHandler(cms.canvasAreaVM.copyFormPieceToClipboard)"><i class="fa fa-clipboard"></i><span class="contextMenuItemText">Copy</span></div>

    </div>

clickHandler立即运行,并返回一个在单击时将被调用的函数。

答案 2 :(得分:-1)

不确定我是否理解您的问题,但也许这可以帮助您:

function MyVM(){
    var self = this;

    this.divsArray = ko.observableArray([]);

    this.handleDiv = function(div){
        //here you can raise your menu with the data provided from the div
        //in the delete callback of the menu, just pass to it the div object and call self.divsArray.remove(div);
    }
}


View:

<div data-bind = "foreach: divsArray">
     <div id = "foo-child" data-bind = "click: $parent.handleDiv($data)"></div>
<div>