backbone.js视图事件不执行

时间:2012-07-18 18:15:12

标签: javascript events backbone.js

我有以下的backbone.js视图如下所示。它工作正常,现在单击表单按钮时不执行click事件。控制台中没有错误,或显示原因的任何其他明显迹象。

window.FormOptionView = Backbone.View.extend({
    template: _.template($('#test-option').html()),
    render: function (eventName) {
        $('#test1').append(this.template(this.model.toJSON()));
         $('#test2').append(this.template(this.model.toJSON()));
        return this;
    }

});


window.AddTestView = Backbone.View.extend({

    template: _.template($('#test-add').html()),

    initialize: function () {
        this.collection.bind("reset", this.render, this);
        this.render();

    },

    events: {
             "click button": "addTest" 
    },

    addTest: function(event){
        event.preventDefault();
        var test = new Test({
            test1: {
                firstName: $("#test1 option:selected").val(),
                lastName: $("#test1Score").val()
            },
            test2: {
                firstName: $("#test2 option:selected").val(),
                lastName: $("#test2Score").val()
            }
        });

        test.add(result);
        app.navigate("tests", true);

    },

    render: function (eventName) {
        $('#content').html(this.template());
        _.each(this.collection.models, function (test) {
             this.renderSelectBox(test);
        }, this);
        return this;
    },

    renderSelectBox: function (item) {
       var optionView = new FormOptionView({
           model: item
       });
       $(this.el).append(optionView.render().el);
    }
});

相应的HTML

        <script type="text/template" id="test-option">
        <option><%= firstName %> <%= lastName %></option>
    </script>

    <script type="text/template" id="test-add">

                <form id="addTest" action="#">
                        <label for="test1">Test1:</label>

                        <select id="test1">
                            <option></option>
                        </select>

                        <label for="test1Score">Score:</label>

                        <input id="test1Score" type="number" />



                        <label for="test2">Test 2:</label>

                        <select id="test2">
                            <option></option>
                        </select>

                        <label for="test2Score">Score:</label>

                        <input id="test2Score" type="number" />


                        <button id="add">Add</button>
                    </form>

           </script>

3 个答案:

答案 0 :(得分:1)

如果没有看到相应的HTML,我最好的猜测是<button>超出了您的观看范围。 Click事件仅附加到View的根元素的子元素。

答案 1 :(得分:0)

发现观看次数el标记对应于一堆空的<div>。不确定为什么,但简单el: $('#content')设法解决问题。感谢

答案 2 :(得分:0)

您的问题正如您已经发现的那样,您的观点未正确处理el

当您的视图呈现时,Backbone通过在视图的this.el上使用jQuery的delegate来连接事件。

如果您没有明确地将el(通过构造函数设置为new V({ el: ... }),在视图的定义中el: ...,或通过调用setElement),那么el将使用各种视图属性as noted in the documentation构建;默认el只是一个简单的<div>。这是空<div>来自的地方。

你这样做:

render: function (eventName) {
    $('#content').html(this.template());
    _.each(this.collection.models, function (test) {
         this.renderSelectBox(test);
    }, this);
    return this;
}

在其他地方你可能正在做一个简单的add_test_view.render()。结果是事件delegate绑定到视图的el(空<div>),并且el永远不会添加到DOM中;如果你有delegate绑定到DOM中没有的东西,那么你永远不会得到任何事件。

如果您在视图定义中说el: '#content',那么Backbone将使用#content作为您的el,您的视图将更像这样:

el: '#content',
//...
render: function (eventName) {
    this.$el.html(this.template());
    this.collection.each(function(test) {
        this.renderSelectBox(test);
    }, this);
    return this;
},
renderSelectBox: function (item) {
    var optionView = new FormOptionView({
        model: item
    });
    this.$el.append(optionView.render().el);
}

请注意,我切换到this.collection.each,Backbone集合有various Underscore methods mixed in,因此您无需手动访问collection.models;我已经切换到this.$el,因为查看已经有this.el的缓存jQuery版本。