2010-11-05 3 views
10

J'essaie de me familiariser avec CoffeeScript et backbone.js, et il me manque quelque chose.Pourquoi mes événements CoffeeScript/backbone.js ne se déclenchent-ils pas?

Ce CoffeeScript:

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

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

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

JavaScript génère le suivant:

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

Mais l'événement click ne se déclenche pas testHandler quand je clique dans test_container.

Si je change le JavaScript sortie:

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

Retrait de la call(this) et la $ annexant, tout fonctionne comme prévu. Qu'est-ce que je rate?

+0

On dirait que vous utilisez jQuery. Voulez-vous ajouter le tag jQuery? – Angiosperm

Répondre

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

est juste un moyen d'invoquer immédiatement une fonction anonyme lors de la spécification d'un récepteur. Il fonctionne essentiellement de cette même façon que:

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

$(function() {}), au moins en jQuery, est un raccourci pour

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

qui exécute la fonction donnée lorsque l'arbre DOM a été entièrement construit. Il semble que ce soit la condition nécessaire pour que votre fonction Backbone.View.extend fonctionne correctement.

+0

Ahh ok merci, et tout ce temps je pensais (function() {}). Call (this) était le même que $ (function() {}). Fait beaucoup plus de sens maintenant. – sefner

5

Pour utiliser CoffeeScript et jQuery ensemble pour les scripts d'application, mettez votre code dans ce genre de modèle:

$ = jQuery 
$ -> 

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

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

Que se passe lorsque la vue, ou au moins view.el est généré dynamiquement? Vous pouvez appeler la méthode view.delegateEvents() pour définir manuellement les gestionnaires d'événement.

Voici un livre de café similaire pour le rendu d'une vue enfant dans une vue parent, puis la délégation des événements de la vue enfant.

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

Essayez d'utiliser la syntaxe de déclaration de classe CoffeeScript, .: par exemple

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

    events: 
    "click" : "addStory" 

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

J'ai trouvé une meilleure solution un peu plus tard .. et aujourd'hui StackOverflow s'est rappelé de lui-même (j'ai gagné un badge :) Donc mieux vaut appeler super dans la toute première ligne du corps de la méthode constructeur et abandonner l'appel à this.delegateEvents . Bonne chance;) – alecnmk

+0

ayant le constructeur comme dans votre exemple avec super() que la première ligne a travaillé pour moi. –

Questions connexes