每个视图实例的主干视图事件触发器

时间:2012-06-27 15:13:10

标签: events backbone.js views

A有一个父视图OpenOrderListView,可以创建OpenOrderViews的实例,其中包含事件。我想要获得的结果是当markCompleted的{​​{1}}按钮被点击时调用一个函数来告诉模型设置那个属性

该功能正在运行,但它在父(OpenOrderListView)内的所有OpenOrderViews上调用,而不仅仅是处理click事件的视图。如何才能在已执行操作的视图上触发此事件?

代码低于

OpenOrderView

OrderView模板

window.OpenOrderListView = Backbone.View.extend({
    el: 'table.openOrders tbody',

    initialize: function() {
        _.bindAll(this,'render');
        this.render();
    },


    render : function() {
        var $openOrders

        var models = this.collection.open();

        for (var i = models.length - 1; i >= 0; i--) {
            console.log('model', models[i]);
            console.log("this.template", this.template);
            new OpenOrderView({'model': models[i], 'el': this.el});
        };

    }
});

window.OpenOrderView = Backbone.View.extend({
    initialize: function() {
        console.log('this', this);
        _.bindAll(this,'render',
                       'markCompleted',
                       'markInProgress');
        this.render();
    },

    events : {
        "click .markCompleted":  "markCompleted",
        "click .markInProgress": "markInProgress",
    },

    markCompleted: function(){
        console.log(this);
        this.model.markCompleted();
    },

    markInProgress: function(){
        console.log("markInProgress",this);
        this.model.markInProgress();
        console.log('markInProgress Complete');
    },

    template : 'template-openOrderView',

    render : function() {
        console.log("View Rendered");
        $(this.el).append(tmpl(this.template, this.model.toJSON()));
    }

   window.Order = Backbone.Model.extend({
    url: function(){ 
        return "/api/order/id/"+this.get("id");
    },

    isCompleted: function(){
        return this.get('status') == "completed";
    },

    isInProgress: function(){
        return this.get('status') == "inProgress";
    },

    isOpen: function(){
        return this.get('status') == "open";
    },

    markCompleted: function(){
        this.set({'status':"completed"});
        console.log('markCompleted');
        return this.save();
    },

    markInProgress: function(){
        this.set({'status':"inProgress"});
        console.log('markInProgress');
        return this.save();
    },

    markOpen: function(){
        this.set({'status':"open"});
        console.log('markOpen');
        return this.save();
    }

});

})

1 个答案:

答案 0 :(得分:6)

所有SubViews共享相同的DOM元素table.openOrders tbody。这是在new OpenOrderView({'model': models[i], 'el': this.el});行中完成的。

所以当你宣布这样的事件时:

events : {
    "click .markCompleted":  "markCompleted"
}

所发生的事情是,与此table.openOrders tbody .markCompleted匹配的所有DOM元素都会与此click事件绑定。

您需要每个SubView拥有自己的this.el DOM元素。

在你的情况下,我认为如果你的SubViews在空中创建他们自己的DOM元素会更好:

// code simplified an not tested
window.OpenOrderView = Backbone.View.extend({
  tagName: 'tr',
  attributes: { class: "order" },

  initialize: function(){
    // don't render() here
  },

  // ... rest of your code

  render: function(){
    this.$el.html(tmpl(this.template, this.model.toJSON()));
    return this;
  }
})

现在看来SubView不是呈现本身,其DOM元素直接附加到页面上,它将是{{{{ 1}}:

ParentView

我认为这是一种非常常见的模式。

PD:您必须修改模板,删除// code simplified an not tested window.OpenOrderListView = Backbone.View.extend({ render : function() { var $openOrders var models = this.collection.open(); for (var i = models.length - 1; i >= 0; i--) { var openOrderView = new OpenOrderView({'model': models[i]}); this.$el.append( openOrderView.render().el ); }; }); 打开/关闭。