2012-03-26 16 views
5

Mam następujący kod:Backbone to zamieszanie

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); 
    } 

}); 

mój problem jest wewnątrz funkcji appendItem. Gdy używam this wewnątrz funkcji appendItem, wierzę, że uważa, że ​​this odnosi się do this.collection aniżeli GoalPanelView. Jak uzyskać this, aby odnieść się do GoalPanelView, a nie do collection? Próbowałem przekazać kolejną zmienną do funkcji, która zawierała zawartość this.elem, ale wydawało się, że nie działa.

Jedną rzeczą, która pracowała kiedy przeniosłem funkcję appendItem do collection i zmienił inicjalizacji wiązać się this.collection.bind('add', appendItem); ale nie chcę umieścić view rzeczy do logiki collection.

+2

Alternatywą jest umieszczenie '_.bindAll (this)' w funkcji initialize. Zapewnia to, że każda funkcja wywołana wewnątrz obiektu zostanie zastosowana z wartością "this" związaną poprawnie z samym obiektem. Przydatne, jeśli piszesz dużo wywołań zwrotnych. – rybosome

Odpowiedz

6

Możesz dodać zakres podczas wiązania obsługi zdarzeń, tak jak poniżej:

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

Zakres ustawia wartość this wewnątrz uchwytu. W twoim przypadku bieżący obiekt.

Edit:Javascript Garden ma wielką wyjaśnieniu dlaczego this.appendItem faktycznie nie nosić zakresu samej funkcji, to po prostu wskaźnik funkcji, a nie wskaźnik metoda. Jednym z dziwactw javascript ..

Edycja 2Backbone Reference - Events/on

0

Można również użyć _.bindAll funkcję podkreślenia w swojej metodzie initialize:

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

Teraz każdy wywołanie dowolnej metody na GoalPanelView (np appendItem) będzie mieć zasięg taki, że odniesienia do this odnoszą się do instancji GoalPanelView.

Można też przejść na liście nazw Sposób jak ciągi jeśli nie chcą zakresem wszystkie metody GoalPanelView

zobaczyć tutaj: http://underscorejs.org/#bindAll

2

Wystarczy zaktualizować (od 0,9 Backbone. 2) właściwy sposób to zrobić:

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


zależności od przypadku stosowania mogą Państwo Warto również rozważyć:

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

to jest właściwy sposób, aby to zrobić. –

+1

Właściwie lepiej byłoby użyć "this.listenTo", więc usunięcie zdarzenia nastąpi automatycznie po wywołaniu usunięcia. W ten sposób zapobiegniesz wyciekom pamięci. –