【问题标题】:Backbone: View Event triggers multiple timesBackbone:多次查看事件触发
【发布时间】:2015-02-24 16:45:35
【问题描述】:

我是 Backbone 的新手。 我想显示一个股票列表,用户可以在其中打开列表中的任何股票并更改股票价值。之后,整个列表应刷新以显示更改的值。

所以我发现最好不仅创建集合,而且创建集合和库存模型列表。

为此,我为主表创建了一个库存集合视图和一个库存模型视图,用于向表中添加行,其中每一行都是一个模型。

所以这是一个集合视图:

App.Views.StockTable = Backbone.View.extend({ ... initialize: function() { this.render(); }, render: function() { this.$el.html(this.template(this.collection)); this.addAll(); return this; }, addOne: function(stock) { var row = new App.Views.StockRow({ model: stock, suppliers: this.suppliers }); return this; }, addAll: function() { var suppliers = new App.Collections.Suppliers(); var that = this; suppliers.fetch({ success: function() { _.each(that.collection.toJSON(), that.addOne, that); } }); return this; } });

这是我的股票行视图:

App.Views.StockRow = Backbone.View.extend({ el: 'tbody', templateRow: _.template($('#stockRow').html()), templatePreview: _.template($('#stockPreview').html()), events: { 'click #open': 'open' ... }, initialize: function() { this.render(); }, render: function() { this.$el.append(this.templateRow(this.model)) .append(this.templatePreview({ stock: this.model, suppliers: this.suppliers })); return this; }, open: function(e) { var element = $(e.currentTarget); element.attr('id', 'hide'); $('#stock' + element.data('id')).slideToggle('fast'); } ... });

我只写了一段代码。问题是,当我单击“#open”时,该事件会触发多次(正确的集合中的数量元素)。因此,当我捕获 e.currentTarget 时,会有许多类似的对象。 我做错了什么?

【问题讨论】:

    标签: javascript backbone.js


    【解决方案1】:

    我怀疑你这里发生了很多事情。

    没有看到您的模板,我怀疑您的每一行 StockRow 都在使用 id="open" 呈现标签。由于 id 值应该是唯一的,因此请在您的链接中使用一个类(例如:class="open"),然后在您的点击处理程序中引用该类:

    events: {
      'click .open': 'open'
    }
    

    接下来,由于StockRow 的每个实例已经有一个与之关联的model 实例,只需使用this.model 而不是尝试从currentTargetdata 属性中查找它。

    open: function () {
      $('#stock' + this.model.id).slideToggle('fast');
    }
    

    但同样,不要在模板中使用id="stock" 属性,而是使用类……比如class="stock-preview"。然后在你的开放中寻找它......

    open: function () {
      this.$el.find('.stock-preview').slideToggle('fast');
    }
    

    我觉得有问题的另一部分是在StockTable 视图的render 方法中对this.addAll(); 的调用。最佳做法是让您的渲染方法渲染状态,而不是让它触发 ajax 调用来获取状态。

    例如,在您的初始化中,您可以设置一些事件处理程序来响应您的集合更改状态(下面是一个不完整的示例,只是希望让您朝着正确的方向前进):

    initialize: function (options) {
      …
      _.bindAll(this, 'render', 'renderRow');
      this.collection.on('add', this.renderRow);
      this.collection.on('reset', this.render);
    },
    
    render: function () {
      this.$el.html(this.tableTemplateWithEmptyTBodyTags());
      this.collection.each(this.renderRow);
      return this;
    },
    
    renderRow: function () {
      var row = new App.Views.StockRow({
        model:      stock,
        suppliers:  this.suppliers
      });
      this.$el.find('tbody').append(row.render().el);
      return this;      
    }
    

    然后在表格视图之外,你可以做一个suppliers.fetch()。当响应返回时应该触发重置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-20
      • 1970-01-01
      • 2012-04-16
      • 2016-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多