如何在Parse.com / backbone.js中保存对象顺序

时间:2012-10-03 19:41:45

标签: javascript jquery ajax backbone.js parse-platform

我有一个属于用户的文件夹列表,我希望他们能够通过拖放重新排序。我可以让拖放工作正常,但我无法弄清楚如何保存结果。我正在使用Parse,我认为这意味着我必须检索每个对象,更改顺序属性,然后重新保存它......但这似乎不起作用,因为它们都以相同的顺序出现。

在排序然后执行.sortable('toArray')之后,我有一个文件夹ID数组,前面加上'folder'一词,所以它看起来像[“folder_ab9gu3nd”,“folder_kwkgiutyqo”,“folder_s856skt8w”]

所以,我想保存文件夹ab9gu3nd,订单0,kwkgiutyqo订单1,s856skt8w订单2。

这是我的代码('result'是包含文件夹ID的数组):

        for(var ii=0; ii<result.length; ii++) {
                            // Get actual id
            var folderId = result[ii].replace('folder_', '');
            var folderOrder = ii;
            var folder = Parse.Object.extend("Folder");
            var query = new Parse.Query(folder);
            query.get(folderId, {
                success: function(folder) {
                    // The object was retrieved successfully.
                    folder.set('order', folderOrder);
                    folder.save();
                }
            });
        }

当我运行它时,文件夹都以订单'2'结束,就像ii的最终值被用于所有文件夹一样。我如何阻止这种情况发生?谢谢!

1 个答案:

答案 0 :(得分:1)

你被两件事愚弄了:

  1. 循环中的var被提升到周围的函数,它们不是循环的本地。
  2. 您的success处理程序是异步触发的,它们是关闭完全相同的folderOrder
  3. 对于第一个,就JavaScript而言,你的循环实际上看起来像这样:

    function whateverItIsCalled() {
        var folderId, folderOrder, folder, query, ii;
        //...
        for(ii = 0; ii < result.length; ii++) {
            //...
            folderOrder = ii;
            //...
        }
        //...
    }
    

    所以整个函数只有一个folderOrder,你的循环只需在每次迭代时为它分配ii

    第二个问题是通常的“循环中的AJAX”问题:您正在构建一系列匿名函数,这些函数是对同一folderOrder变量的闭包。结果是,您的所有三个success处理程序最终都引用了相同的folderOrder值,并且当它们被触发时,循环将完成并且folderOrder将具有循环中的最后一个值;你案件中的最后一个值是两个。

    要解决您的问题,您只需要将各个folderOrder值分别添加到各种success处理程序中。一种方法是使用函数生成成功处理程序:

    function makeSuccess(folderOrder) {
        return function(folder) {
            folder.set('order', folderOrder);
            folder.save();
        }
    }
    

    然后:

    query.get(folderId, {
        success: makeSuccess(folderOrder)
    });
    

    另一种常见方法是使用自执行函数有效地为循环体创建不同的范围:

    for(var ii = 0; ii < result.length; ii++)
        (function(ii) {
            // Same stuff you currently have...
        })(ii);
    

    您采取的方法取决于个人偏好。