2010-11-05 16 views
10

Próbuję zapoznać się z CoffeeScript i backbone.js, i muszę czegoś przegapić.Dlaczego moje zdarzenia CoffeeScript/backbone.js nie wyzwalają?

Ten coffeescript:

MyView = Backbone.View.extend 
    events: { 
    "click" : "testHandler" 
    } 

    testHandler: -> 
    console.log "click handled" 
    return false 

view = new MyView {el: $('#test_container')} 
view.render() 

generuje następujące JavaScript:

(function() { 
    var MyView, view; 
    MyView = Backbone.View.extend({ 
    events: { 
     "click": "testHandler" 
    }, 
    testHandler: function() { 
     console.log("click handled"); 
     return false; 
    } 
    }); 
    view = new MyView({ 
    el: $('#test_container') 
    }); 
    view.render; 
}).call(this); 

Ale wydarzenie click nie ognia testHandler po kliknięciu w test_container.

Gdybym zmienić wyjściowy JavaScript do:

$(function() { 
    var MyView, view; 
    MyView = Backbone.View.extend({ 
    events: { 
     "click": "testHandler" 
    }, 
    testHandler: function() { 
     console.log("click handled"); 
     return false; 
    } 
    }); 
    view = new MyView({ 
    el: $('#test_container') 
    }); 
    view.render; 
}); 

Zdejmowanie call(this) i dołączenie $, wszystko działa zgodnie z oczekiwaniami. czego mi brakuje?

+0

wygląda na to, że używasz jQuery. Czy chcesz dodać znacznik jQuery? – Angiosperm

Odpowiedz

7
(function() {}).call(this); 

to sposób na natychmiastowe wywołanie anonimowej funkcji podczas określania odbiornika. Działa to w zasadzie ten sam sposób, jak:

this.method = function() {}; 
this.method(); 

$(function() {}), przynajmniej w jQuery, jest skrótem

$(document).ready(function() {}) 

czyli daną funkcję, gdy drzewo DOM została wykończona. Wygląda na to, że jest to warunek konieczny do prawidłowego działania funkcji Backbone.View.extend.

+0

Ahh ok dzięki, i przez cały ten czas myślałem (function() {}). Call (this) było takie samo jak $ (function() {}). Teraz ma o wiele więcej sensu. – sefner

5

Do korzystania coffeescript i jQuery razem dla skryptów aplikacyjnych, umieścić swój kod w tego typu szablonu:

$ = jQuery 
$ -> 

    MyView = Backbone.View.extend 
    events: 
     "click": "testHandler" 
    testHandler: -> 
     console.log "click handled" 
     false 

    view = new MyView el: $('#test_container') 
    view.render() 
2

Co się dzieje, gdy widok, albo przynajmniej view.el jest generowana dynamicznie? Możesz wywołać metodę view.delegateEvents(), aby ręcznie ustawić obsługę zdarzeń.

Oto podobny coffeescript do renderowania ChildView w ParentView, a następnie delegowania zdarzeń childView.

window.ParentView = Backbone.View.extend 
    addOne: (thing) -> 
    view = new ChildView({model: thing}) 
    this.el.append view.render().el 
    view.delegateEvents() 
3

Spróbuj użyć klasy coffeescript deklaracji składni, np .:

class BacklogView extends Backbone.View 
    constructor: (@el) -> 
    this.delegateEvents this.events 

    events: 
    "click" : "addStory" 

    # callbacks 
    addStory: -> 
    console.log 'it works!' 
+0

Znalazłem lepsze rozwiązanie jakiś czas później ... i dzisiaj StackOverflow przypomniał sobie o sobie (zdobyłem odznakę :) Lepszym rozwiązaniem jest wywołanie super w pierwszej linii ciała metody konstruktora i porzucenie połączenia z this.delegateEvents . Powodzenia;) – alecnmk

+0

o konstruktorze jak w twoim przykładzie z super() jak dla mnie pierwsza linia. –

Powiązane problemy