jQuery Sortable的connectWith方法会调用update方法两次。

31
在下面的代码中,当从列表 sortable1 移动项目到 sortable2 时,更新函数会被调用两次。我需要仅调用一次该函数:
$("#sortable1 tbody, #sortable2 tbody").sortable({
    connectWith: '.connectedSortable tbody',
    helper: fixHelper,
    handle : '.handle',
    update : function () {
        var order = $('#sortable1 tbody').sortable('serialize');
    }    
}).disableSelection();
8个回答

63

9
值得注意的是,这里有一个有趣的值 thisupdate 会被触发两次,即在元素被拖出的列表和元素被拖入的列表中。ui.item.parent() 指的是被拖动元素的父级。如果你想知道为什么它能够工作 :) - nuala

13

Stefan的答案很好,但它没有涉及谜题中的另一部分,因此在这里说明一下-以防有人(像我一样)无法立即理解。这应该使您能够在update()函数中处理所有内容,而不必干扰receive()(只有在发生容器间移动时才会触发):

update: function(e,ui) {
    if (this === ui.item.parent()[0]) {
        if (ui.sender !== null) {
          // the movement was from one container to another - do something to process it
          // ui.sender will be the reference to original container
        } else {
          // the move was performed within the same container - do your "same container" stuff
        }
    }
}

6

试试这个:

update: function(e,ui) {
    if (!ui.sender) {
        //your code here
    }
}

1
这样做不行,因为你没有在同一个容器内看到动作。除非你想要分别处理它们。 - userfuser
1
我的端上百分之百工作正常。 感谢@Code Slinger先生为我节省时间。 - Rejwanul Reja
这在我的端上也能工作。太棒了! - HPWD

5

1
那么,您如何处理同一列表内以及连接列表中的排序呢?您如何知道该遵守哪个排序方式? - Jason
1
@Jason:在http://forum.jquery.com/topic/sortables-update-callback-and-connectwith找到了答案。 - Stefan

3
为了仅调用一次更新功能,最好使用“停止事件”,它表示拖放已完成。它只会触发一次,无论是在相同列表中还是连接的列表中进行拖放。建议使用stop event。请注意保留HTML标记。
$('.selector').sortable({
  stop: function(event, ui ) {
    ...
  }
})

2
如何使用remove、receive和update捕获所有更改并将其作为数组发送到服务器?
演示:http://jsfiddle.net/r2d3/p3J8z/
$(function(){

    /* Here we will store all data */
    var myArguments = {};   

    function assembleData(object,arguments)
    {       
        var data = $(object).sortable('toArray'); // Get array data 
        var step_id = $(object).attr("id"); // Get step_id and we will use it as property name
        var arrayLength = data.length; // no need to explain

        /* Create step_id property if it does not exist */
        if(!arguments.hasOwnProperty(step_id)) 
        { 
            arguments[step_id] = new Array();
        }   

        /* Loop through all items */
        for (var i = 0; i < arrayLength; i++) 
        {
            var image_id = data[i]; 
            /* push all image_id onto property step_id (which is an array) */
            arguments[step_id].push(image_id);          
        }
        return arguments;
    }   

    /* Sort images */
    $('.step').sortable({
        connectWith: '.step',
        items : ':not(.title)',
        /* That's fired first */    
        start : function( event, ui ) {
            myArguments = {}; /* Reset the array*/  
        },      
        /* That's fired second */
        remove : function( event, ui ) {
            /* Get array of items in the list where we removed the item */          
            myArguments = assembleData(this,myArguments);
        },      
        /* That's fired thrird */       
        receive : function( event, ui ) {
            /* Get array of items where we added a new item */  
            myArguments = assembleData(this,myArguments);       
        },
        update: function(e,ui) {
            if (this === ui.item.parent()[0]) {
                 /* In case the change occures in the same container */ 
                 if (ui.sender == null) {
                    myArguments = assembleData(this,myArguments);       
                } 
            }
        },      
        /* That's fired last */         
        stop : function( event, ui ) {                  
            /* Send JSON to the server */
            $("#result").html("Send JSON to the server:<pre>"+JSON.stringify(myArguments)+"</pre>");        
        },  
    });
});

这里是解决方案的完整说明:http://r2d2.cc/2014/07/22/jquery-sortable-connectwith-how-to-save-all-changes-to-the-database/

1

这并不是一个真正的 bug,你只是绑定到了错误的事件。 - Brad Gessler

0
update: function(e, ui) {
    var draggedOut = this !== ui.item.parent()[0] && !$.contains(this, ui.item.parent()[0]);
    var draggedIn = ui.sender !== null;
    var sameList = !draggedOut && !draggedIn;

    if (sameList || draggedIn) {
        // Do stuff
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接