为什么我的CoffeeScript/backbone.js事件没有触发?

10

我正在尝试熟悉CoffeeScript和backbone.js,但我肯定漏掉了些什么。

这是CoffeeScript的代码:

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

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

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

生成以下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);

但是当我在 test_container 中点击时,click 事件不会触发 testHandler

如果我将输出的 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)并添加$后,一切都按预期工作。我错过了什么吗?


看起来你正在使用jQuery。你想添加jQuery标签吗? - Angiosperm
4个回答

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

立即调用函数表达式(IIFE)是一种在指定接收器的同时立即调用匿名函数的方法。它的工作原理基本上与以下方式相同:

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

$(function () {}),至少在jQuery中,是以下代码的简写:

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

当DOM树完全构建时运行给定的函数。似乎这是您的Backbone.View.extend函数正常工作所必需的条件。


啊,好的,谢谢。这整个时间我一直以为 (function (){}).call(this) 和 $(function(){}). 是一样的。现在更有意义了。 - sefner

5

要将CoffeeScript和jQuery一起用于应用程序脚本,请将您的代码放在这种模板中:

$ = jQuery
$ ->

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

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

3

尝试使用CoffeeScript类声明语法,例如:

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

  events:
    "click" : "addStory"

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

我后来找到了更好的解决方案...今天StackOverflow提醒了我(我获得了一些徽章 :) 因此,更好的解决方案是在构造函数方法体的第一行调用super并放弃对this.delegateEvents的调用。祝你好运 ;) - alecnmk
在你的例子中,将构造函数设为super()作为第一行对我很有效。 - Pete Brumm

2

当视图或者至少是view.el被动态生成时会发生什么?你可以调用view.delegateEvents()方法手动设置事件处理程序。

以下是类似的Coffeescript代码,用于在ParentView中呈现ChildView,然后委派childView的事件。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接