【问题标题】:D3 dispatch pass in arguments and calling contextD3 调度传递参数和调用上下文
【发布时间】:2014-12-12 21:39:21
【问题描述】:

我了解在 D3 中,根据this example,调度可用于将事件触发到多个可视化。

我也明白,如果我想从一个对象调用一个调度并传入上下文,我可以使用apply,如here所示。

但是,我很难将来自 D3 调度的参数与我想要的上下文结合起来。

// create my dispatcher
var probeDispatch = d3.dispatch("probeLoad");
var line_count = 0;

// load a file with a bunch of JSON and send one entry every 50 ms
var lines = [[0,1],[1,2],[2,0]];
var parse_timer = window.setInterval(
    function () {
        parse_dispatch();
    }, 50
);

function parse_dispatch(){
  // send two arguments with my dispatch
  probeDispatch.probeLoad(lines[line_count][0], lines[line_count][1]);
  line_count += 1;
  if(line_count >= lines.length){
    //line_count = 0
    window.clearInterval(parse_timer);
  }
}

// my chart object
var genChart = function(label){
  this.label = label;
  // assume I've drawn my chart somewhere here
  probeDispatch.on(("probeLoad."+this.label), this.probeParse);
  // this next line isn't working, since the
  // console.log in probeLoad still returns undefined
  probeDispatch.probeLoad.apply(this);
};

genChart.prototype = {
    probeParse: function(probeData, simTime) {

      // How do I get the context from the object that's calling probeParse
      // into the probeParse scope?
      var self = this;
      console.log(self.label);
    }
};

new genChart("pants");
new genChart("shirt");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

【问题讨论】:

    标签: javascript oop d3.js prototype


    【解决方案1】:

    当您在控制台中看到"pants" 时,它确实正确设置了上下文。

    但是有3个未定义的记录,因为你也调用

      // send two arguments with my dispatch
      probeDispatch.probeLoad(lines[line_count][0], lines[line_count][1]);
    

    不提供上下文。

    你需要

    probeDispatch.probeLoad.apply(instanceOfGenChart, [lines[line_count][0], lines[line_count][1]]);
    

    但启用它还需要将parse_dispatch 移到页面下方。

    // create my dispatcher
    var probeDispatch = d3.dispatch("probeLoad");
    var line_count = 0;
    
    // load a file with a bunch of JSON and send one entry every 50 ms
    var lines = [[0,1],[1,2],[2,0]];
    var parse_timer = window.setInterval(
        function () {
            parse_dispatch();
        }, 50
    );
    
    // my chart object
    var genChart = function(label){
      this.label = label;
      // assume I've drawn my chart somewhere here
      probeDispatch.on(("probeLoad."+this.label), this.probeParse);
      // this next line isn't working, but I don't know what to do
      probeDispatch.probeLoad.apply(this);
    };
    
    genChart.prototype = {
        probeParse: function(probeData, simTime) {
    
          // How do I get the context from the object that's calling probeParse
          // into the probeParse scope?
          var self = this;
          console.log(self.label);
        }
    };
    
    var instanceOfGenChart = new genChart("pants");
    
    function parse_dispatch(){
      // send two arguments with my dispatch
      probeDispatch.probeLoad.apply(instanceOfGenChart, [lines[line_count][0], lines[line_count][1]]);
      line_count += 1;
      if(line_count >= lines.length){
        //line_count = 0
        window.clearInterval(parse_timer);
      }
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

    【讨论】:

    • 感谢您的回答,但事实证明我问错了问题。我现在已经对其进行了编辑(包括我正在考虑使用来自多个图表的相同调度的事实)并且我希望我可以从这里将它拼凑起来,如果我这样做了,我会将其标记为正确的。抱歉,我没有更具体。
    • @Seanny123 不用担心。我在您的回答中添加了一些关于 bind 的内容。
    【解决方案2】:

    结果是把上下文带入函数,我必须bind()它,原因我不太清楚。

    // create my dispatcher
    var probeDispatch = d3.dispatch("probeLoad");
    var line_count = 0;
    
    // load a file with a bunch of JSON and send one entry every 50 ms
    var lines = [[0,1],[1,2],[2,0]];
    var parse_timer = window.setInterval(
        function () {
            parse_dispatch();
        }, 50
    );
    
    function parse_dispatch(){
      // send two arguments with my dispatch
      probeDispatch.probeLoad(lines[line_count][0], lines[line_count][1]);
      line_count += 1;
      if(line_count >= lines.length){
        //line_count = 0
        window.clearInterval(parse_timer);
      }
    }
    
    // my chart object
    var genChart = function(label){
      this.label = label;
      // assume I've drawn my chart somewhere here
      probeDispatch.on(("probeLoad."+this.label), this.probeParse.bind(this));
    };
    
    genChart.prototype = {
        probeParse: function(probeData, simTime) {
    
          // How do I get the context from the object that's calling probeParse
          // into the probeParse scope?
          var self = this;
          console.log(self.label);
        }
    };
    
    new genChart("pants");
    new genChart("shirt");
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

    由meetamit添加

    Bind 是这里的解决方案,因为它将范围锁定到genChart.prototype. probeParse 的“实例”。这样parse_dispatch(调用者)就不需要知道关于范围的任何事情。相当于这样:

    // my chart object
    var genChart = function(label){
      this.label = label;
      var self = this;
      var probeParseBound = function() { self.probeParse(); };
      probeDispatch.on(("probeLoad."+this.label), probeParseBound);
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-10
      • 2015-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-20
      • 1970-01-01
      相关资源
      最近更新 更多