0

参照用に完全なソースが必要な場合に備えて、このモジュールのコードを含むペーストビンを作成しました。

D3でSVGグラフィックとして描かれた米国の地図があります。各パスには複数のイベント リスナーがバインドされていますが、jQuery に依存するのは 1 つだけです。マップ上でクリック イベントが発生すると、D3 ツールチップが作成されます。

ペーストビンの39行目

buttonTemplate : "<div id = 'tooltip_template'>" + 
            "<div class = 'county_data'></div>" +
            "<img src = '/static/images/delete.png' width = '28' height = '28' class = 'delete_logo' id = 'close_tooltip' />" +
            "<div id = 'no_client_message'></div>" +
            "<button id = 'add_prospective_market' class = 'tooltip_button'>Prospective Market</button>" +
            "<button id = 'add_market' class = 'tooltip_button'>Market County</button>" +
            "<button id = 'remove_market' class = 'tooltip_button'>Remove Market</button></div>"

HTML DOM 要素として。

3 つのボタンにはそれぞれ、73 行目のイベント委譲を介して割り当てられたリスナーがあります。

$("body") 
        .on("click", "#add_market", function(){
            if (thisObj._currentCounty.color != thisObj._fillColors.market)
                marketHandler(0);
            else
                $("#no_client_message").text("Market button has been disabled");
        })
        .on("click", "#add_prospective_market", function(){
            if (thisObj._currentCounty.color != thisObj._fillColors.prospect)
                marketHandler(1);
            else
                $("#no_client_message").text("Prospective market button has been disabled");
        })
        .on("click", "#remove_market", function(){
            marketHandler(2);
        })

そして、211行目にハンドラー関数を次のように定義しています

//executes ajax post request to add a new client-county relationship.  Type is 0 for
//new market, 1 for new prospective market and 2 for remove this client-county relationship
var marketHandler = function(type){
    $.ajax({
        url : "marketHandler/",
        type : "POST",
        data : {"data" : JSON.stringify({
                            "client" : thisObj._currentClient.id,
                            "county" : thisObj._currentCounty.id,
                            "type" : type
                        })
                },
        dataType : "json",
        success : function(results){
            if (results.success == "true"){

            /*
                console.log("Market handler type: " + type);

                var fillColor = "";

                if (type == 0)
                    fillColor = thisObj._fillColors.market;

                else if (type == 1)
                    fillColor = thisObj._fillColors.prospect;

                else
                    fillColor = thisObj._fillColors.neutral;

                d3.selectAll($("#" + thisObj._currentCounty.id))
                    .style("fill", fillColor);

                closeTooltipHandler();
            */
                //hack to get the fill color change to apply.  There is some conflict going
                //on between the jquery and d3 event handlers.  While the function executes,
                //the change of the fill is not applied on success.
                thisObj._clientSelect.trigger("change");
            } else
                alert(results.message);
        }
    })
}

私の問題は、Ajax関数が成功し、results.success == "true"条件が満たされている間、通常は色の変更が実行されることです

d3.selectAll($("#" + thisObj._currentCounty.id))
  .style("fill", fillColor);

マップには適用されません。代わりに、現時点で唯一の解決策は、ビューのドロップダウン リストで変更イベントをトリガーすることです。これは機能しますが、色変更操作を実行するためだけに冗長なデータ フェッチが必要になるため、必要以上に複雑になります。

私は当初、Ajax関数内にネストされているためだと思っていたので、success関数を次のように変更しました

var fillColor = "";
var colorChange = false;

$.ajax({
  ...
  ...
  success : function(results) {
    if (results.success == "true){
      colorChange = true;

      //get fillColor hex value
    }
  }
});

if (colorChange){
  d3.selectAll($("#" + thisObj._currentCounty.id))
    .style("fill", fillColor);
}

しかし、これもうまくいきませんでした。

4

1 に答える 1

0

コメントで逆風が示唆したように、これは実際にはスコープの問題であり、成功のコールバックで匿名関数を使用して解決しました。私の成功ハンドラは今です

success : function(results){
  if (results.success == "true"){

    if (type == 0)
      fillColor = thisObj._fillColors.market;

    else if (type == 1)
      fillColor = thisObj._fillColors.prospect;

    else
      fillColor = thisObj._fillColors.neutral;

    closeTooltipHandler();

    //need anonymous function to resolve scope issue between D3 and jQuery
    (function(thisObj, fillColor){
      d3.selectAll($("#" + thisObj._currentCounty.id))
        .style("fill", fillColor)
    })(thisObj, fillColor);

  } else
    alert(results.message);
}
于 2013-09-27T12:11:51.320 に答える