我有一个属于用户的文件夹列表,我希望他们能够通过拖放重新排序。我可以让拖放工作正常,但我无法弄清楚如何保存结果。我正在使用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的最终值被用于所有文件夹一样。我如何阻止这种情况发生?谢谢!
答案 0 :(得分:1)
你被两件事愚弄了:
var
被提升到周围的函数,它们不是循环的本地。success
处理程序是异步触发的,它们是关闭完全相同的folderOrder
。对于第一个,就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);
您采取的方法取决于个人偏好。