jquery Sortable connectWith 两次调用更新方法

Posted

技术标签:

【中文标题】jquery Sortable connectWith 两次调用更新方法【英文标题】:jquery Sortable connectWith calls the update method twice 【发布时间】:2011-03-30 09:37:11 【问题描述】:

在下面的代码中,当一个项目从列表sortable1 移动到sortable2 时,更新函数会被调用两次。虽然我只需要调用一次该函数:

$("#sortable1 tbody, #sortable2 tbody").sortable(
    connectWith: '.connectedSortable tbody',
    helper: fixHelper,
    handle : '.handle',
    update : function () 
        var order = $('#sortable1 tbody').sortable('serialize');
        
).disableSelection();

【问题讨论】:

【参考方案1】:

答案来自:http://forum.jquery.com/topic/sortables-update-callback-and-connectwith

update: function(e,ui) 
    if (this === ui.item.parent()[0]) 
        //your code here
    

【讨论】:

值得注意的是this是这里的有趣值。 update 被触发两次,即由元素被拖出的列表和元素被拖入的列表触发。 ui.item.parent() 指被拖动元素的父元素。如果您想知道为什么会这样:)【参考方案2】:

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
        
    

【讨论】:

【参考方案3】:

试试这个:

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

【讨论】:

这行不通,因为这样您就看不到同一个容器内的运动了。除非您想单独处理它们。 它 100% 对我有用。感谢@Code Slinger 先生节省了我的时间。 这也对我有用。太棒了!【参考方案4】:

您应该使用接收事件 (http://jqueryui.com/demos/sortable/#event-receive)。

在http://bugs.jqueryui.com/ticket/3178查看最底部的分辨率。

【讨论】:

那么你如何处理同一个列表和连接列表中的排序?你怎么知道应该尊重哪一个? @Jason:在forum.jquery.com/topic/…找到答案【参考方案5】:

如何使用 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/

【讨论】:

【参考方案6】:

为了只调用一次更新函数,最好使用stop event,表示拖拽已经完成。无论拖放是在同一个列表还是连接列表中,它都只会触发一次。

$('.selector').sortable(
  stop: function(event, ui ) 
    ...
  
)

【讨论】:

【参考方案7】:

我刚碰到这个。这是 jQuery UI 中的一个错误,请参阅 http://bugs.jqueryui.com/ticket/4872#comment:2

我评论说我是否可以唤醒任何人,何时会有修复。社区驱动开发的乐趣:P

【讨论】:

这不是真正的错误,您只是绑定到错误的事件。【参考方案8】:
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
    

【讨论】:

以上是关于jquery Sortable connectWith 两次调用更新方法的主要内容,如果未能解决你的问题,请参考以下文章

jQuery Sortable的自身序列化

为啥 jQuery.sortable 的这个 ajax 会多次执行更新?

jQuery UI:sortable('toArray') 返回一个空数组

jquery sortable div拖放文本不能被ckeditor编辑

<div> 上的 jquery .sortable()

jquery ui的sortable拖动克隆问题