1

私は自分のコードでループクロージャーの問題を思いついたと思います。私はこの記事を読みまし た。これは大きな助けになりました。最近、この記事で参照されている「LoopingWithAClosure」のセクションに似た問題が発生しました。私は彼らの解決策を試しましたが、それでも私の問題は解決しませんでした。私はどこでも解決策を探してきましたが、私はいつも記事の中でそれを見つけます。

私はjqueryuiを使用していくつかのliをドラッグ可能にし、それらをコンテナーにドロップするときに、そのliに固有の変数(ノード)を使用する必要があります。問題は、ノード(およびインデックス)が常に最後のノードであるということです(したがって、クロージャーの問題)。

これが私のコードです(問題を特定しやすくするために少し簡略化しました):

function makeDraggable(node, i) {
        $("#rightTab li#" + node.id).draggable({
            containment: 'div#container',
            stack: 'div#container',
            scroll: false,
            revert: 'invalid',
            helper: function() {
                return $(this).children().clone();
            },
            start: function(event, ui) {
                $(this).children().css('opacity', 0);
            },
            stop: function(event, ui) {
                $(this).children().css('opacity', 1);
            }
        });

        $("#vis").droppable({
            drop: test(node, i)
        });
    }

    function test(noder, index) {
        return function(event, ui) {
            alert(index);
            //stuff with node.
        }
    }

    function appendInfo(nodes) {
        for(var i = 0; i < nodes.length; i++) {
            $("#rightTab #content ul").append("<li id=" + nodes[i].id + "><div></div></li>");

            if(visualization.hasImageLabel) {
                interfaceHandler.handleImageLabel(nodes[i]);
            }
            if(visualization.hasTextLabel) {
                interfaceHandler.handleTextLabel(nodes[i]);
            }

            makeDraggable(nodes[i], i);
        }
    }

(関数テストで)インデックスに警告すると、常に9(最大配列長)が出力され、ノードも常に最後のノードになります。

(悪い英語でごめんなさい)

4

2 に答える 2

1

$("#vis").droppable({...})ループ全体のすべての反復を呼び出しています。dropこれにより、10個のイベントハンドラーが設定されます。パラメータとして渡された最後の1つ(node_nine、9)のみが起動されます。

ui.draggableコールバック内の値を確認してください。ドロップされた要素が何であるかを教えてくれます。

于 2013-01-11T02:41:29.217 に答える
1

問題は、$("#vis").droppable(...)以前に定義されたドロップ可能な機能を置き換えるため、クロージャーで解決できないことです。

インデックスを知ることが重要な場合は、ドラッグ可能な各ノードに、を使用して独自のインデックスを認識させ、ではなく、で1回だけ.data(...)呼び出してみてください。$("#vis").droppable(...)appendInfo()makeDraggable()

function appendInfo(nodes) {
    for(var i = 0; i < nodes.length; i++) {
        $("#rightTab #content ul").append("<li id=" + nodes[i].id + "><div></div></li>");
        if(visualization.hasImageLabel) {
            interfaceHandler.handleImageLabel(nodes[i]);
        }
        if(visualization.hasTextLabel) {
            interfaceHandler.handleTextLabel(nodes[i]);
        }
        makeDraggable(nodes[i], i);
        $(node).data('index', i); //<<< node is now aware of its own index
    }
    $("#vis").droppable({
        drop: function(event, ui) {
            alert(ui.draggable.data('index'));//I think???
            //stuff with node.
        }
    });
}

インデックスを知る必要がない場合はui.draggable、を設定または取得せずに、としてドラッグ可能なものにアクセスできます.data()

于 2013-01-11T02:54:45.800 に答える