2011-08-31 18 views
6

Desidero che i pannelli vengano ricreati quando vengono cliccati.Passare il contesto con il bind in backbone.js

Tuttavia, quando mi esibisco un clic ottengo il seguente:

Uncaught TypeError: Cannot call method 'get' of undefined 

Sembra che il "questo" che sto registrazione è infatti il ​​modello stesso:

_callbacks: Object 
_changed: true 
_escapedAttributes: Object 
_previousAttributes: Object 
attributes: Object 
cid: "c0" 
collection: r.d 
id: "f5589ba4-a0aa-dd86-9697-30e532e0f975" 
__proto__: n 

I ho difficoltà a capire perché l'appropriato "questo" non è conservato passando il mio contesto in model.bind.

Ecco il mio codice:

// Models 
window.Panel = Backbone.Model.extend({ 

    defaults: function(){ 
     return { 
      flipped: false, 
     }; 
    }, 

    toggle: function(){ 
     this.save({flipped: !this.get("flipped")}); 
    }, 

}); 


// Collections 

window.PanelList = Backbone.Collection.extend({ 

    model:Panel, 

    localStorage: new Store("panels"),  

    flipped: function(){ 
     return this.filter(function(panel){ return panel.get("flipped"); }) 
    } 
}); 


// Global collection of Panels 
window.Panels = new PanelList; 

// Panel View 

window.PanelView = Backbone.View.extend({ 

    tagName: 'div', 

    template: _.template($("#panel-template").html()), 

    events: { 
     "click" : "toggle" 
    }, 

    initialize: function(){ 
     this.model.bind("change", this.render, this) 
     $(this.el).html(this.template(this.model.toJSON())); 
    },  

    render: function(){  
     console.log(this); 
     var flipped = this.model.get("flipped") 
     if (flipped){ 
      $(this.el).addClass("flip"); 
     } else{ 
      $(this.el).removeClass("flip"); 
     }   
     return this 
    }, 

    toggle: function(){ 
     this.model.toggle(); 
    } 
}); 

risposta

16

Il modo in cui spina dorsale-y per farlo è quello di utilizzare la funzione _.bindAll(...) fornita da sottolineatura:

initialize: function(){ 
    _.bindAll(this, "render"); 
    this.model.bind("change", this.render) 
    $(this.el).html(this.template(this.model.toJSON())); 
} 

Cosa _.bindAll fa è documentato here , ma è essenzialmente costruito esattamente per questo scopo. Se si desidera impostare this correttamente in tutte le funzioni dell'oggetto, è possibile chiamare _.bindAll(this) senza alcun elenco di funzioni. Tendo ad avere questa funzione di binding globale nella maggior parte delle mie opinioni.

13

Ho incontrato lo stesso problema e finito per usare il metodo di _.bind underscore.js(), invece. Ho interrogato SO per una risposta, ed è stata la risposta che ho ricevuto.

Prova a cambiare: this.model.bind("change", this.render, this)

A: this.model.bind("change", _.bind(this.render, this))

+1

Flawless. Spacchi. – nottombrown

Problemi correlati