从外面敲出可拆卸的拖放

时间:2014-12-28 14:57:31

标签: jquery knockout.js drag-and-drop knockout-sortable

也许有人可以帮助我。
我在webapp中获得了大量的视图。左侧有产品列表,右侧有类别列表。产品应该在类别中拖动。
产品列表是一个observableArray。现在,当列表有超过1000个条目时,我们遇到了性能问题(特别是在IE上)。因此,因为产品本身不会改变,我们将它们从敲除绑定中取出,将它们连接在一个字符串中并仅附加一个节点。当然,淘汰赛可排序的绑定不再起作用了......

这是类别的模板:

<div data-bind="sortable: {data: Products, beforeMove: $root.verifyProducts}, attr: { 'data-max': MaxProducts }">
<div class="menuEditTab2CatDragItem clearfix" data-bind="attr: { 'data-prodid': Id }">
    <div class="menuEditTab3ProdsNameText" data-bind="text: Name"></div>
    <div class="pull-right" style="margin-left:8px;"><i style="margin-top:-4px;" class="icon-remove" data-bind="click: $parent.removeProduct"></i>

    </div>
    <div class="pull-left menuEditTab3ProdsIdText">ID: <span data-bind="text: Id"></span>
    </div>
</div>

这是左侧产品列表的js代码:

function fillAllProductsTab() {
        var parts = '';
        allProducts.forEach(function (item) {
            parts += '<div id="f_all_' + item.Id + '" >' +  // draggable="{data: $data, options:{containment: \'\#menuEditTab3Ce\', revert: \'invalid\'}}"
                '<div class="menuEditTab2CatDragItem">' +
                '<div>' + item.Name + '</div><div class="clearfix menuEditTab3ProdsIdText">' +
                '<div class="pull-left">ID: <span>' + item.Id + '</span></div><div class="pull-right">' +
                '<span>' + item.Price + '</span> €</div></div></div></div>';
        });
        $("#allp").append(parts);
    };

现在我的想法是我可以在附加后立即手动初始化产品列表中的可拖动插件:

    $('#allp > div').draggable({
        //connectToSortable: '#sortable',
        helper: 'clone',
        revert: 'invalid',
        cursor: 'move'
    });

所以,我的问题是,我不能让他们一起工作。左侧列表是可拖动的,右侧的可排序也正常,但连接不起作用。没有掉落事件正在发生......一般来说这可能吗?如果有人有想法让这项工作?

1 个答案:

答案 0 :(得分:5)

sortable插件收到拖动的项目时,它希望该元素附加一些元数据以指向应该删除的实际数据项。元数据通过KO的ko.utils.domData.set函数附加。它被称为:

ko.utils.domData.set(element, key, value);

因此,在将项目放入可排序项之前,您需要附加此元数据。类似的东西:

$(".drag-item").draggable({
    connectToSortable: ".container",
    helper: "clone",
    start: function(event, ui) {
        ko.utils.domData.set(event.target, "ko_dragItem", true);
    }
});

当删除可拖动项目时,插件会尝试两种方法来创建副本以实际放入可排序的observableArray中。首先,它在项目上查找clone函数。其次,它运行在可排序绑定中配置的dragged函数,并使用返回值作为项。

因此,可排序的绑定可能如下所示:

<div class="container" data-bind="sortable: { data: tasks, dragged: handleDraggedItem }">
    <div class="item" data-bind="text: name">
    </div>
</div>

handleDraggedItem喜欢:

this.handleDraggedItem = function(item, event, ui) {
    return new Task(ui.item.text());
};

以下是jsFiddle中的示例:http://jsfiddle.net/rniemeyer/aewLbnrm/

因此,您需要决定构建项目的方式/位置。您可以使用可拖动的start方法执行此操作,只需从dragged函数返回该项,或者像我在dragged函数中的示例中那样执行此操作。希望一切都有意义!