我正试图进入骨干网,并且有以下尝试做图像库。我正在尝试使用渲染与集合中的模型。我将展示该集合的第一个元素,但我想添加对简单重新渲染下一个元素的支持,但我不知道如何做到这一点。
我在我的模型上实现了next和previous,如下所示:
arc.Item = Backbone.Model.extend({
next: function () {
if (this.collection) {
return this.collection.at(this.collection.indexOf(this) + 1);
}
},previous: function () {
if (this.collection) {
return this.collection.at(this.collection.indexOf(this) - 1);
}
}
});
这里的问题(可能比我要问的更多)是在loadNext方法中。如何获取此集合中的当前位置并将其递增?
arc.ItemsGalleryView = Backbone.View.extend({
el: $('#mig-container'),
events: {'click .next-btn' : 'loadNext',
'click .previous-btn':'loadPrevious' },
template:_.template($('#mig-image-tmp').text()),
initialize: function() {
_.bindAll( this, 'render' );
// render the initial state
var thisModel=this.collection.first();
this.render(thisModel);
},
render: function(xModel) { // <- is it ok to do it this way?
var compiled=this.template(xModel.toJSON());
this.$el.html(compiled);
return this;
},
loadNext: function(){
console.log('i want to load Next');
this.render(this.collection.next()); // <- how would I do this
this.render(this.collection.first().next()); // <- this works by always giving me the second.
// I need to replace first with current
},
loadPrevious: function(){
console.log('i want to load Previous');
}
或者有更好的方法来实现这个吗?
事先提前编辑#1
arc.ItemsGalleryView = Backbone.View.extend({
el: $('#mig-container'),
events: {'click .next-btn' : 'loadNext', 'click .previous-btn':'loadPrevious' },
template:_.template($('#mig-image-tmp').text()),
initialize: function() {
_.bindAll( this, 'render' );
this.render(this.collection.first()); // <- this works correct
},
render: function(xModel) {
console.log(xModel.toJSON());
var compiled=this.template(xModel.toJSON());
this.$el.html(compiled);
return this;
},
loadNext: function(){
console.log('i want to load next');
this.render(this.collection.next()); // <- this doesn't seem to do anything, event is called correctly but doesn't seem to move to next element
},
However if I adjust to this, it will load the 3rd element of the array
loadNext: function(){
console.log('i want to load Previous');
this.render(this.collection.at(2));
},
我如何使用this.collection.next()来获取此行为?
THX
答案 0 :(得分:1)
你正在寻找的是一种使用Collection
来操纵下一个/上一个东西的方法。你目前只有它在模型上。这是我在项目中使用的基础Collection
:
App.Collection = Backbone.Collection.extend({
constructor: function(models, options) {
var self = this;
var oldInitialize = this.initialize;
this.initialize = function() {
self.on('reset', self.onReset);
oldInitialize.apply(this, arguments);
};
Backbone.Collection.call(this, models, options);
},
onReset: function() {
this.setActive(this.first());
},
setActive: function(active, options) {
var cid = active;
if ( active instanceof Backbone.Model ) {
cid = active.cid;
}
this.each(function(model) {
model.set('current', model.cid === cid, options);
});
},
getActive: function() {
return this.find(function(model) {
return model.get('current');
});
},
next: function() {
return this.at(this.indexOf(this.getActive()) + 1);
},
prev: function() {
return this.at(this.indexOf(this.getActive()) - 1);
}
});
它可能并不完美,但它对我有用。希望它至少可以让你走上正轨。以下是我如何使用它:
var someOtherCollection = App.Collection.extend({
model: MyModel
});
答案 1 :(得分:1)
kalley的回答是正确的,但我会再举一个例子。
我会接受将当前模型保留在state
模型中的想法,并从那里开始工作。您也可以在state
模型中存储其他应用程序信息。
您的模型声明如下所示。请注意,我已将previous
重命名为prev
。 Backbone.Model
已经有previous
方法,我们不想覆盖它。
var Model = Backbone.Model.extend({
index:function() {
return this.collection.indexOf(this);
},
next:function() {
return this.collection.at(this.index()+1) || this;
},
prev:function() {
return this.collection.at(this.index()-1) || this;
}
});
拥有包含所选模型的通用Backbone.Model
:
var state = new Backbone.Model();
在视图中,您将监听状态模型的更改并相应地进行渲染:
var View = Backbone.View.extend({
el: '#mig-container'
template:_.template($('#mig-image-tmp').html()),
events: {
'click .prev' : 'prev',
'click .next' : 'next'
},
initialize:function() {
this.listenTo(state,'change:selected',this.render);
state.set({selected:this.collection.at(0)});
},
render:function() {
var model = state.get('selected');
this.$el.html(this.template(model.toJSON()));
return this;
},
next:function() {
// get the current model
var model = state.get('selected');
/* Set state with the next model, fires a change event and triggers render.
Unless you are at the last model, then no event will fire.
*/
state.set({selected:model.next()});
},
prev:function() {
var model = state.get('selected');
state.set({selected:model.prev()});
}
});
这是demo。我喜欢state
模型方法,因为我没有在我的模型中存储应用程序状态信息。
如果你不喜欢state
模型方法,你总是可以把它扔在地板上:
/ .. code above ../
initialize:function() {
this.model = this.collection.at(0);
this.render();
},
render:function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
},
next:function() {
this.model = this.model.nxt();
this.render();
},
prev:function() {
this.model = this.model.prev();
this.render();
}