我有一个属于用户的文件夹列表,我希望它们能够通过拖放来重新排序。我可以使拖放正常工作,但是我不知道如何保存结果。我使用的是Parse,我认为这意味着我必须检索每个对象,更改order属性,然后重新保存它……但这似乎不起作用,因为它们都以相同的顺序输出。
[排序后再执行.sortable('toArray'),我有一个文件夹ID数组,前面带有单词“ folder”,因此看起来像[“ folder_ab9gu3nd”,“ folder_kwkgiutyqo”,“ folder_s856skt8w”]。
所以,我要保存顺序为0的文件夹ab9gu3nd,顺序1为kwkgiutyqo以及顺序2为s856skt8w。
这是我的代码(“结果”是带有文件夹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的最终值都被使用了一样。如何阻止这种情况的发生?
您被两件事所骗:
var
被提升到周围的功能,它们不在循环内。success
处理程序是异步触发的,它们是完全相同的folderOrder
的闭包。对于第一个,就JavaScript而言,您的循环实际上看起来像这样:
function whateverItIsCalled() {
var folderId, folderOrder, folder, query, ii;
//...
for(ii = 0; ii < result.length; ii++) {
//...
folderOrder = ii;
//...
}
//...
}
所以整个功能只有一个folderOrder
,并且您的循环在每次迭代时都简单地为其分配ii
。
[第二个问题是通常的“ AJAX in a loop”问题:您正在构造一系列匿名函数,它们是对同一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);
您采用哪种方法是个人喜好问题。