0

我正在尝试从主干函数内的 d3 函数中引用主干render函数。我现在必须引用其他 Backbone 函数来做一些主干的事情,但不能通过使用 this/that 方法(我使用 this/ƒthis)引用它来访问它们:

define([
  // this is for require.js file modularization 
], function(){
  return Backbone.View.extend({
    initialize: function(options){
      //CODE
      this.render();
    },

    render: function(options){
      // HOW I ACCESS THE BACKBONE VIEW IN NESTED SITUATIONS
      var ƒthis = this;    

      //NORMAL RENDERING
      if (!options) {        
        // Do some stuff, get some vars

        // compile the template

        // D3 stuff
        var lineData = ({...});
        var pathFunction = d3.svg.line()
        var beatUnwindingPaths = [......];

        var beatContainer = d3.select('#beatHolder'+this.parent.cid);
        var beatPath = beatContainer //.append('g')
            .insert('path', ':first-child')
            .data([beatUnwindingPaths[0]])
            .attr('d', pathFunction)
            .attr('class', 'beat')
   //THIS IS WHERE I WANT TO REFERENCE THE FUNCTION TO BE CALLED, AND HOW I THINK IT SHOULD BE CALLED
            .on('click', ƒthis.toggle);
   //BUT CURRENTLY I AM ONLY LIMITED TO CALLING A FUNCTION DECLARED WITHIN THE BACKBONE render func(), so it would look like this:
            .on('click', toggle);

   //CURRENTLY I AM HAVING TO DECLARE THE FUNCTIONS INSIDE RENDER
        function unroll() {
          //do some stuff
        };
        function reverse() {
        };
        $('#a').on('click', unroll);
        $('#b').on('click', reverse);
      }
    },

// THIS IS THE FUNCTION I WANT TO CALL
    toggle: function(){
       //DO some stuff to the other BackBone models, collections and other cool stuff
    }
  });
});

如何toggle从 D3 代码中访问 Backbone 功能?

错误代码来自切换功能本身(以前工作过,所以我想弄清楚为什么现在没有),错误出现在 313 上,而不是 314 上,我的浏览器控制台总是关闭一行。我放了一个 console.log() 来查看我在函数中得到的 ƒthis.toggle ,但在切换 bool 值时出错。

311 toggle: function(){
312   //switch the selected boolean value on the model
313   this.model.set('selected', !this.model.get('selected'));
314   //re-render it, passing the clicked beat to render()
315   this.render(this.model);
316   // log.sendLog([[1, "beat" + this.model.cid + " toggled: "+!bool]]);
317   dispatch.trigger('beatClicked.event');
318 }

我从在模板中渲染圆圈切换到让 d3 创建它(所以我们可以使用 d3 函数对其进行动画处理),我认为对象以某种方式失去了与模型的绑定。在这方面工作......

4

1 回答 1

2

这不是 D3/Backbone 问题,它只是 Javascript。您不能传递稍后调用的对象方法并期望this在该方法中工作,除非您以一种或另一种方式绑定它:

var myObject = {
    method: function() {
        this.doSomeStuff();
    },
    doSomeStuff: function() {
        console.log("stuff!");
    }
};

myObject.method(); // "stuff!"

// pass this method somewhere else - this is
// effectively what you do with an event handler
var myMethod = myObject.method;

myMethod(); // TypeError: Object [object global] has no method 'doSomeStuff'

第二部分失败,因为调用myObject.myMethod()绑定thismyObject,但是将方法分配给变量(或将其分配为事件处理程序)没有(在大多数情况下,this绑定到window,但 D3 将重新分配this给您设置处理程序的 DOM 元素)。

标准修复是 1) 将其包装在一个函数中:

var myMethod = function() {
    myObject.method();
};

myMethod();  // "stuff!"

或 2) 以某种方式将其绑定到对象,例如在您的 Backboneinitialize方法中(下划线_.bindAll为此目的提供了有用的实用程序):

Backbone.View.extend({
    initialize: function(options){
        _.bindAll(this, 'toggle');
        // now you can pass this.toggle around with impunity
    },
    // ...
});
于 2013-05-21T18:31:42.863 回答