我是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时,有许多类似的对象。 我做错了什么?
答案 0 :(得分:0)
我怀疑你有很多事情要发生。
如果没有看到您的模板,我怀疑您的每个StockRow
行都会使用id="open"
呈现标记。由于id值应该是唯一的,因此请在链接中使用一个类(例如:class="open"
),然后在点击处理程序中引用该类:
events: {
'click .open': 'open'
}
接下来,由于StockRow
的每个实例都已经有一个与之关联的model
实例,因此只需使用this.model
而不是尝试从data
中查找它currentTarget
的属性。
open: function () {
$('#stock' + this.model.id).slideToggle('fast');
}
但是,再次,不要在模板中使用id="stock"
属性,而是使用类...说class="stock-preview"
。然后在你的公开场合寻找...
open: function () {
this.$el.find('.stock-preview').slideToggle('fast');
}
另一件看起来有问题的是this.addAll();
视图的render
方法中对StockTable
的调用。最佳做法是让渲染方法呈现状态,而不是让它触发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()
。当响应返回时应该触发重置。