如何使用coffeescript使用`this`和`_this`(胖箭头)?

nac*_*cab 10 coffeescript d3.js

我正在使用D3函数each,它接受一个回调函数并调用它this作为参数传递,但我需要同时访问this_this.这是coffeescript代码:

@x = d3.scale.ordinal().domain(d3.range(@model.geneExpressions[0].length)).rangeBands([0, width])    

getRow = (row) =>
    cell = d3.select(this).selectAll(".cell")
        .data(row)
      .enter().append("rect")
        .attr("x", (d,i) => @x(i))    

rows = @heatmap.selectAll(".row")
    .data(@model.geneExpressions)
  .enter().append("g")
    .each(getRow)                    
Run Code Online (Sandbox Code Playgroud)

以及它生成的javascript:

    var _this = this;    

this.x = d3.scale.ordinal().domain(d3.range(this.model.geneExpressions[0].length)).rangeBands([0, width]);    

getRow = function(row) {
        var cell;
        return cell = d3.select(_this).selectAll(".cell").data(row).enter().append("rect").attr("x", function(d, i) {
          return _this.x(i);
        })
      };    

rows = this.heatmap.selectAll(".row").data(this.model.geneExpressions).enter().append("g").attr("class", "row").each(getRow);
Run Code Online (Sandbox Code Playgroud)

我怎样才能this在这一行中使用coffeescript 并保持一致?:

return cell = d3.select(this) ...
Run Code Online (Sandbox Code Playgroud)

问题是我无法将@x作为参数传递给each并使用细箭头而不是胖箭头(因为那时我无法访问@x),除非我重写D3函数,这似乎有点过分.

mu *_*ort 13

所以你有这个结构:

@x = ...
getRow = (row) =>
    d3.select(@)...attr('x', (d, i) => @x(i))
rows = ...each(getRow)
Run Code Online (Sandbox Code Playgroud)

但是你需要getRow成为一个正常的->函数,以便它获得DOM元素,@并且你需要attr回调作为绑定=>函数,所以@x工作,对吧?

立即想到两种可能性:

  1. 使用通常的JavaScript var that = this;技巧的CoffeeScript形式.
  2. 使用命名绑定函数进行attr回调.

第一个看起来像这样:

that   = @
getRow = (row) ->
    cell = d3.select(@)
        .selectAll(".cell")
        .data(row)
        .enter().append("rect")
        .attr("x", (d,i) -> that.x(i))    
Run Code Online (Sandbox Code Playgroud)

第二个是这样的:

x_at_i = (d, i) => @x(i)
getRow = (row) ->
    cell = d3.select(@)
        .selectAll(".cell")
        .data(row)
        .enter().append("rect")
        .attr("x", x_at_i)
Run Code Online (Sandbox Code Playgroud)