我有以下代码在集合同步后发生:
adGeneration: function() {
var child = this.children.findByIndex(this.children.length - 1);
console.log(child.model.toJSON());
eventer.trigger('generate:new:ad', child);
},
我遇到的问题是,在第一次同步后,child
元素是一个空白模型:
第一次:
Object {id: "5-vp39kv3uiigxecdi", size: 26, price: "9.84", face: "( ⚆ _ ⚆ )"}
每次之后:
Object {length: 40, models: Array[41], _byId: Object, _listeningTo: Object, _listenId: "l14"…}
ProductsCollection
define(["backbone", "lodash", "fonts/products/model", "eventer"],
function(Backbone, _, ProductModel, eventer) {
'use strict';
var ProductsCollection = Backbone.Collection.extend({
model: ProductModel,
sort_key: 'price',
url: '/api/products',
offset: 0,
initialize: function() {
this.listenTo(eventer, 'fetch:more:products', this.loadMore, this);
},
comparator: function(item) {
return item.get(this.sort_key);
},
sortByKey: function(field) {
this.sort_key = field;
this.sort();
},
parse: function(data) {
return _.chain(data)
.filter(function(item) {
if(item.id) {
return item;
}
})
.map(function(item){
item.price = this.formatCurrency(item.price);
return item;
}.bind(this))
.value();
},
formatCurrency: function(total) {
return (total/100).toFixed(2);
},
loadMore: function() {
this.offset += 1;
this.fetch({
data: {
limit: 20,
skip: this.offset
},
remove: false,
success: function(collection) {
this.add(collection);
}.bind(this)
});
}
});
return ProductsCollection;
});
包含制作集合视图的LayoutView。该集合是在layoutview的显示中获取的
define(["marionette", "lodash", "text!fonts/template.html",
"fonts/controls/view", "fonts/products/view", "fonts/products/collection", "eventer"],
function(Marionette, _, templateHTML, ControlsView, ProductsView,
ProductsCollection, eventer) {
'use strict';
var FontsView = Marionette.LayoutView.extend({
regions: {
controls: '#controls',
products: '#products-list'
},
template: _.template(templateHTML),
initialize: function() {
this._controlsView = new ControlsView();
this._productsView = new ProductsView({
collection: new ProductsCollection({
reorderOnSort: false,
sort: false
})
});
this.listenTo(this._productsView.collection, 'sync', this.loading, this);
this.listenTo(eventer, 'fetch:more:products', this.loading, this);
this.listenTo(eventer, 'products:end', this.productsEnd, this);
},
onRender: function() {
this.getRegion('controls').show(this._controlsView);
this.getRegion('products').show(this._productsView);
this.loading();
},
onShow: function() {
this._productsView.collection.fetch({
data: {
limit: 20
}
})
},
productsEnd: function() {
this.loading();
this.$el.find('#loading').html("~ end of catalogue ~")
},
loading: function() {
var toggle = this.$el.find('#loading').is(':hidden');
this.$el.find('#loading').toggle(toggle);
}
});
return FontsView;
});
AdsView:
define(["marionette", "lodash", "text!ads/template.html", "eventer"],
function(Marionette, _, templateHTML, eventer) {
'use strict';
var AdsView = Marionette.ItemView.extend({
template: _.template(templateHTML),
ui: {
ad: '.ad'
},
initialize: function() {
this.listenTo(eventer, 'generate:new:ad', this.generateNewAd, this);
},
onShow: function() {
// Set add image onShow
this.ui.ad.prop('src', '/ad/' + this.randomNumber());
},
generateNewAd: function(childView) {
var newAd = this.ui.ad.clone(),
element = childView.$el,
elementId = childView.model.get("id");
newAd.prop('src', '/ad/' + this.randomNumber());
$("#" + elementId).after(newAd);
},
randomNumber: function() {
return Math.floor(Math.random()*1000);
},
setUpAd: function() {
this.ui.ad.prop('src', '/ad/' + this.randomNumber());
}
});
return AdsView;
});
答案 0 :(得分:2)
我认为您的问题出在ProductsCollection.loadMore
方法中。在您success
的{{1}}回调中,
fetch
幕后发生的事情是,在调用function(collection) { this.add(collection); }
回调之前,Backbone将首先对您的数据运行success
。默认情况下,在Collection.set()
内,您的数据将被解析为set
返回的模型数组,如果找到任何新模型,它们将ProductsCollection.parse
添加到您现有的集合中(请注意,除非您将add
传递到{ remove: false }
个选项,否则系统会删除您上次提取中不的模型。请参阅Collection.set
)< / p>
那么,当您在fetch
中执行fetch
时会发生什么,在第一个loadMore
之后称为,Backbone将首先fetch
来自服务器的所有模型(从add
返回)然后调用ProductsCollection.parse
的{{1}}回调,这基本上是最后一次success
。它fetch
实例的add
是什么。不是add
,一个模型数组,而是一个具有属性ProductsCollection
的Backbone对象,它包含一个原始的模型数组。因此,奇怪的输出:
collection.models
只需删除models
回调(这是不必要的),Object {length: 40, models: Array[41], _byId: Object, _listeningTo: Object,
_listenId: "l14"…}
的最后一个子视图应该是从最后返回的模型中呈现的视图。