Вопрос

У меня есть список папок, принадлежащих пользователю, и я хочу, чтобы он мог изменять их порядок путем перетаскивания.Я могу заставить перетаскивание работать нормально, но не могу понять, как сохранить результаты.Я использую Parse и думаю, это означает, что мне нужно получить каждый объект, изменить атрибут порядка, а затем повторно сохранить его...но, похоже, это не работает, поскольку все они выходят в одном и том же порядке.

После сортировки и выполнения .sortable('toArray') у меня есть массив идентификаторов папок, к которому добавляется слово "папка", поэтому он выглядит примерно так: ["folder_ab9gu3nd", "folder_kwkgiutyqo", "folder_s856skt8w"].

Итак, я хочу сохранить папку ab9gu3nd с порядком 0, kwkgiutyqo с порядком 1 и s856skt8w с порядком 2.

Вот мой код («результат» — это массив с идентификаторами папок):

        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. Твой varвнутри цикла передаются в окружающую функцию, они не являются локальными для цикла.
  2. Твой 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);

Какой подход вы выберете, зависит от ваших личных предпочтений.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top