Backbone.js简单视图事件未触发。

5
有人可以告诉我为什么以下代码无法正常工作吗?我期望当我点击链接时会弹出警告框。
<body>
    <a class="newnote" href="#">Add new note</a>
</body>

<script>
var note = Backbone.Model.extend({});

var notes = Backbone.Collection.extend({
    model: note,
    url: '<?= $this->createUrl('/filenotes/api'); ?>'
});

var note_view = Backbone.View.extend({
    el: 'table',

});

var Appview = Backbone.View.extend({
    el: $('body'),

    events: {
        "a click" : "showForm"
    },
    initialize: function(){
        //alert('hi');  
    },
    showForm: function(){
        alert('hi');
    }
});

var v = new Appview();
</script>

这里有一个jsfiddle示例http://jsfiddle.net/neilcharlton/yj5Pz/1/

3个回答

19

您的$("body")选择器在DOM加载之前触发,因此它返回空值并且永远不会绑定到链接。

Backbone对象定义是使用对象字面量定义的,这意味着它们在定义时立即被评估,而不是在实例化模型时才评估。

代码示例:

Backbone.View.extend({foo: "bar"})

这个函数在功能上与这个函数相同:

var config = {foo: "bar"};
Backbone.View.extend(config);

由于您将$("body")选择器作为el的值,因此它会在解析View配置时立即计算,这意味着DOM尚未加载,因此不会返回任何内容。

有许多解决方案...所有这些解决方案都涉及延迟选择器的计算,直到DOM加载完成。

我个人最喜欢的方法是在DOM加载后,在实例化视图时传递选择器:

var AppView = Backbone.View.extend({
  // don't specify el here
});

$(function(){
  // after the DOM has loaded, select it and send it to the view
  new AppView({ el: $("body") });
}

另外,就像Skylar所说的那样,您的事件声明错误。

这里有一个工作的JSFiddle:http://jsfiddle.net/yj5Pz/5/


1
更好的做法是依赖于Backbone自动使用jQuery包装你的el,当它需要时:{ el: 'body', ... },现在this.$el将是你要寻找的jQuery元素。 - rfunduk
+1 rfunduk - 新的v0.9系列backbone使得处理变得更加容易。现在不需要手动将您的el包装在jQuery选择器中,因为backbone已经为我们完成了这个工作。 - Derick Bailey

9

首先,事件对象的语法如下:

events: {
    "click a" : "showForm"
},

1
除了Derick的回答之外,还要注意DOM元素的范围。我试图在一个元素上触发一个简单的点击事件,但我的View.el引用了一个非直接父元素,然后由于某种原因(可能是递归错误)它没有起作用。当我将el更改为“body”css选择器时,一切都很好。

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