0

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

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>
4

3 回答 3

1

在没有看到相应的 HTML 的情况下,我最好的猜测是您<button>超出了您的视图范围。单击事件仅附加到视图根元素的子元素。

于 2012-07-18T18:23:53.633 回答
0

正如您已经发现的那样,您的问题是您的视图没有el正确处理它。

当你的视图被渲染时,Backbone 通过delegate在视图的this.el.

如果您没有明确设置el(通过构造函数 as new V({ el: ... }),在视图的定义中el: ...,或通过调用setElement),那么将使用文档中所述的el各种视图属性来构造;默认只是一个简单的. 这就是你的 empty s 的来源。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 集合混合了各种 Underscore 方法,因此您不必collection.models手动访问;我也切换到了,this.$el因为 view 已经有一个缓存的 jQuery 版本的this.el.

于 2012-07-18T19:19:55.883 回答
0

刚刚发现viewsel标签对应的是一堆空<div>的s。不知道为什么,但一个简单的el: $('#content')设法解决了这个问题。谢谢

于 2012-07-18T18:31:34.583 回答