1

実現しようとしている機能の簡単な説明: 左側にソース オブジェクトのリストがあり、ユーザーは新しいアイテムをリストから右側のリストにドラッグできます。したがって、アイテムは右側のリストに追加されます。 ; 右側のリストからアイテムを削除することもできます。右側のリストは、変更されるたびに保存されます。(どのように/どこに保存されているかの詳細は問題ではないと思います...)

JavaScript 要素と DOM 要素の領域で少しタイミングに問題があります。右側のリストに既にある項目は削除できます。DOM要素の「削除/削除」タイプのアイコン/ボタンで起動するコードがいくつかあります。これは、DOMから要素を視覚的かつ永久に削除することになっています(つまり、「ショーで戻す必要はありません」 ')。この視覚的な変化は、JS が DOM ツリーをトラバースして新しく更新されたリストを構築するときに構築される JSON オブジェクトにも現れるはずです。

ただし、この .remove() が呼び出された直後に実行されるこの JS コードのチャンクでは、削除されたはずの要素がまだ JSON オブジェクトに表示されます。これは良くない。

ここで動作するコードの関連ビットであると私が信じているものを次に示します。これは Web ブラウザーに存在します。これの多くは document.ready() 関数にあります。特定のリストにはサブセクションを含めることもできるため、サブリストはパーツとループになります。

クリック時の定義:

$('body').on('click', '.removeLine', function() {
var parent=$(this).parent().parent().parent();     //The button is a few DIVs shy of the outer container
var List=$(this).closest('article');     //Another parent object, containing all the 
parent.fadeOut( 300, 
    function() {
        parent.slideUp(300);
        parent.remove(); 
    }
);
sendList(List);    //  This builds and stores the list based on the DOM elements
});

そして後で、この関数定義:

function sendList(List) {
var ListArray=[], 
    subListArray=[], 
    itemsArray = [], 
    subListName = "";
var ListTitle = encodeText(List.find('.title').html());

            // loop through the subLists
List.find('.subList').each(
        function(index, element) {
            subListName=($(this).find('header > .title').html());  // Get sublist Title
            subListID=($(this).attr('id'));               // Get subList ID

            // loop through the line items
            itemsArray=[];
            $(this).find('.itemSearchResult').each(
                function(index, element) {
                            //  Build item Array
                    if( $(this).attr('data-itemid')!= item ) {
                        itemArray.push( $(this).attr('data-itemid'));
                    }
                }
            );

             // Build SubList Array with items Array
            subListArray.push(
                    {
                        "subListName": subListName,
                        "subListID" : subListID,
                        "items" : itemsArray
                    }
            );
        }
); <!-- end SubList Loop -->

// Complete List Array with subListArray
ListArray ={
"ListName": ListTitle,
"ListID": List.attr('id'),
"subLists": subListArray
};
        // Send New List to DataLists Object - the local version of storage
updateDataLists(ListArray);
        // Update remote storage
window.location= URLstring + "&$Type=List" + "&$JSON=" + JSON.stringify(ListArray) + "&$objectID=" + ListArray.ListID;

};

「parent.remove()」ステップと「sendList()」への呼び出しの相互作用のように思われますが、それらのワイヤーが交差しています。視覚的には画面上のオブジェクトは正しいように見えますが、ストレージに送信されているデータを確認すると、視覚的に削除されたオブジェクトを介して送信されます。

ありがとう、J

PS。おそらくおわかりのように、私たちは Javascript のことは初めてなので、コードが非常に効率的または適切でない可能性があります。しかし...それは動作します!(まあ、この問題を除いて。そして、私たちはこの問題に数回遭遇しました。回避策はありますが、ここで何が起こっているのかを理解したいと思います。JS のより深い仕組みを学んで、これらを作成しないようにしてください。そもそもの問題。)

4

1 に答える 1

4

ここではいくつかのことが行われていますが、非同期プログラミングの観点からアプローチして説明します。

要素が DOM から削除されるsendList に呼び出しています。要素は、コールバックが実行されるまで DOM から削除されませんfadeOut(300 ミリ秒かかります)。

sendList関数は を開始した直後に呼び出されますが、プログラムは終了するまでfadeOut呼び出しを待機しません。それがコールバックの目的です。sendListfadeOut

したがってsendList、DOM要素が次のように削除された後、コールバックを呼び出すことでアプローチします。

$('body').on('click', '.removeLine', function() {
    var el = $(this); //maintain a reference to $(this) to use in the callback
    var parent=$(this).parent().parent().parent();     //The button is a few DIVs shy of the outer container
    parent.fadeOut( 300, 
        function() {
            parent.slideUp(300);
            parent.remove(); 
            sendList(el.closest('article'));
       }
    );
});
于 2013-10-19T21:41:36.690 に答える