0

ユーザーに属するフォルダーのリストがあり、ドラッグ アンド ドロップで並べ替えできるようにしたいと考えています。ドラッグ アンド ドロップは正常に機能しますが、結果を保存する方法がわかりません。私はParseを使用しています。つまり、各オブジェクトを取得し、順序属性を変更してから再保存する必要があると思います...しかし、すべて同じ順序で出てくるため、うまくいかないようです。

並べ替えてから .sortable('toArray') を実行すると、フォルダー ID の配列が作成され、先頭に「folder」という単語が追加されるので、["folder_ab9gu3nd", "folder_kwkgiutyqo", "folder_s856skt8w"] のようになります。

そこで、フォルダ ab9gu3nd を順序 0、kwkgiutyqo を順序 1、s856skt8w を順序 2 で保存したいと思います。

これが私のコードです(「結果」はフォルダー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();
                }
            });
        }

これを実行すると、すべてのフォルダーに ii の最終値が使用されたかのように、すべてのフォルダーの順序が「2」になります。これが起こらないようにするにはどうすればよいですか?

4

1 に答える 1

1

あなたは2つのことにだまされています:

  1. varループ内のsは周囲の関数に吊り上げられており、ループのローカルではありません。
  2. ハンドラーは非同期でトリガーされ、まったく同じsuccessクロージャです。folderOrder

最初のものについては、JavaScriptに関する限り、ループは実際には次のようになります。

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

したがってfolderOrder、関数全体に対して1つだけがあり、ループiiは各反復で関数に割り当てるだけです。

2番目の問題は、通常の「ループ内のAJAX」問題です。同じfolderOrder変数のクロージャである一連の無名関数を作成しています。その結果、3つのsuccessハンドラーすべてが同じfolderOrder値を参照することになり、トリガーされるまでに、ループは終了folderOrderし、ループの最後の値になります。あなたの場合の最後の値は2です。

問題を解決するには、さまざまなハンドラーに個別folderOrderの値を取得する必要があります。success1つの方法は、関数を使用して成功ハンドラーを生成することです。

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

その後:

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

もう1つの一般的なアプローチは、自己実行関数を使用して、ループ本体の個別のスコープを効果的に作成することです。

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

どのアプローチを取るかは、個人的な好みの問題です。

于 2012-10-03T20:13:44.330 に答える