2012-03-26 18 views
5

Tengo el siguiente código:Backbone esta confusión

var GoalPanelView = Backbone.View.extend({ 

    // Bind to the goal panel DOM element 
    el: $("#sidebar-goals"),  

    // Initialize the collection 
    initialize: function() { 
     this.collection = Goals; 
     this.collection.bind('add', this.appendItem); 
    }, 

    // Create a new goal when a user presses enter in the enter goal input 
    createOnEnter: function(e) { 
     if (e.keyCode != 13) return; 
     this.addItem(); 
     //Goals.create(this.newAttributes());   
    }, 

    // Add the goal item to the goal list 
    addItem: function() { 
     var goal = new Goal(); 
     goal.set(this.newAttributes()); 
     var goalsElem = this.el; 
     this.collection.add(goal); 
     $(this.el).children("#enter-goal").val(''); 
    }, 

    // Append DOM element to the parent el 
    appendItem: function(item) { 
     var goalView = new GoalView({ 
      model: item, 
     }); 
     $(this.elem).append(goalView.render().el); 
    } 

}); 

Mi problema está dentro de la función appendItem. Cuando uso this dentro de la función appendItem, creo que cree que el this se refiere al this.collection en lugar del GoalPanelView. ¿Cómo obtendré el this para referirme al GoalPanelView en lugar del collection? Intenté pasar otra variable a la función appendItem que contenía los contenidos de this.elem, pero no pareció funcionar.

Una cosa que funcionó fue cuando me cambiaron la función appendItem en el collection y cambió la inicialización de unirse a this.collection.bind('add', appendItem); pero no quiero poner las cosas view en la lógica collection.

+2

Una alternativa es poner '_.bindAll (this)' en la función de inicialización. Eso asegura que cualquier función llamada dentro del objeto será aplicada con el valor de 'this' ligado apropiadamente al objeto mismo. Útil si estás escribiendo muchas devoluciones de llamada. – rybosome

Respuesta

6

Puede agregar un ámbito al enlazar un controlador de eventos, así:

this.collection.bind('add', this.appendItem, this); 

El alcance define el valor de this dentro del manejador. En tu caso, el objeto actual.

Editar:Javascript Garden tiene una gran explicación por qué no this.appendItem efectivamente desarrolle el alcance de la función en sí, es sólo un puntero de función, no un puntero método. Una de las peculiaridades de Javascript ..

Editar 2Backbone Reference - Events/on

0

También puede utilizar la función de subrayado _.bindAll en su initialize método:

initialize: function() { 
    _.bindAll(this); 
    this.collection = Goals; 
    this.collection.bind('add', this.appendItem); 
} 

Ahora, cualquier llamada a cualquier método de GoalPanelView (por ejemplo, appendItem) tendrá un alcance tal que las referencias a this se refieren a la instancia GoalPanelView.

También se puede pasar en una lista de nombres de métodos como cadenas si no quiere alcance todos los métodos de GoalPanelView

ve aquí: http://underscorejs.org/#bindAll

2

Sólo para actualizar (a partir de 0,9 Backbone. 2), la forma correcta de hacerlo es:

initialize: function() { 
    this.collection.on("add", this.appendItem, this); 
    ... 
} 


Dependiendo de su caso de uso, es posible que una También quiero considerar:

initialize: function() { 
    this.listenTo(this.collection, "add", this.appendItem); 
    ... 
} 
+0

esta es la forma correcta de hacerlo –

+1

En realidad, sería mejor usar "this.listenTo", por lo que la desvinculación del evento se producirá automáticamente al llamar a eliminar. De esta forma evitará fugas de memoria. –