2010-11-05 19 views
10

Estoy tratando de familiarizarme con CoffeeScript y backbone.js, y me falta algo.¿Por qué mis eventos CoffeeScript/backbone.js no se activan?

Este CoffeeScript:

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

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

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

genera el siguiente 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); 

Pero el evento no se dispara clicktestHandler cuando hago clic en test_container.

Si cambio de la salida JavaScript para:

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

Extracción de la call(this) y añadiendo el $, todo funciona como se esperaba. ¿Qué me estoy perdiendo?

+0

Parece que estás usando jQuery. ¿Desea agregar la etiqueta jQuery? – Angiosperm

Respuesta

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

es solo una forma de invocar inmediatamente una función anónima mientras se especifica un receptor. Funciona básicamente esta misma forma que:

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

$(function() {}), al menos en jQuery, es la abreviatura de

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

que se ejecuta la función dada cuando el árbol DOM ha sido totalmente construido. Parece que esta es la condición necesaria para que su función Backbone.View.extend funcione correctamente.

+0

Ahh ok gracias, y todo este tiempo estaba pensando (function() {}). Call (this) era lo mismo que $ (function() {}). Tiene mucho más sentido ahora. – sefner

5

Para poder utilizar CoffeeScript y jQuery juntos por guiones de aplicación, ponga su código en este tipo de plantilla:

$ = jQuery 
$ -> 

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

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

¿Qué ocurre cuando la vista, o al menos view.el se genera de forma dinámica? Puede llamar al método view.delegateEvents() para configurar manualmente los eventhandlers.

Aquí hay un coffeescript similar para representar un ChildView en un ParentView y luego delegar los eventos de childView.

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

Trate de usar la sintaxis de declaración de la clase CoffeeScript, por ejemplo .:

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

    events: 
    "click" : "addStory" 

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

He encontrado una mejor solución algún tiempo después ... y hoy StackOverflow se acordó de sí mismo (me gané una insignia :) Así que la mejor solución es llamar a super en la primera línea del cuerpo del método constructor y abandonar la llamada a this.delegateEvents . Buena suerte;) – alecnmk

+0

teniendo el constructor como en su ejemplo con super() como la primera línea funcionó para mí. –

Cuestiones relacionadas