添加模型到集合问题
Backbone.js Adding Model to Collection Issue
我正在构建一个测试应用程序在Backbone.js(我的第一个应用程序使用Backbone)。应用程序是这样的:
- 从服务器"Plans"加载数据
- 构建计划列表并显示到屏幕
- 有一个添加新计划的按钮
- 一旦新计划被添加,添加到收集(现在不保存到服务器)
- 重定向到索引页并显示新的集合(包括您刚刚添加的计划)
我怎样才能防止这种情况的发生?我已经找到了一种方法来做到这一点,但这绝对不是正确的方式。下面您将找到我的代码示例。谢谢你的帮助。
PlansListView视图:
var PlansListView = Backbone.View.extend({
tagName : 'ul',
initialize : function()
{
_.bindAll( this, 'render', 'close' );
//reset the view if the collection is reset
this.collection.bind( 'reset', this.render , this );
},
render : function()
{
_.each( this.collection.models, function( plan ){
$( this.el ).append( new PlansListItemView({ model: plan }).render().el );
}, this );
return this;
},
close : function()
{
$( this.el ).unbind();
$( this.el ).remove();
}
});//end
NewPlanView保存方法
var NewPlanView = Backbone.View.extend({
tagName : 'section',
template : _.template( $( '#plan-form-template' ).html() ),
events : {
'click button.save' : 'savePlan',
'click button.cancel' : 'cancel'
},
intialize: function()
{
_.bindAll( this, 'render', 'save', 'cancel' );
},
render : function()
{
$( '#container' ).append( $( this.el ).html(this.template( this.model.toJSON() )) );
return this;
},
savePlan : function( event )
{
this.model.set({
name : 'bad plan',
date : 'friday',
desc : 'blah',
id : Math.floor(Math.random()*11),
total_stops : '2'
});
this.collection.add( this.model );
app.navigate('', true );
event.preventDefault();
},
cancel : function(){}
});
路由器(默认方法):
index : function()
{
this.container.empty();
var self = this;
//This is a hack to get this to work
//on default page load fetch all plans from the server
//if the page has loaded ( this.plans is defined) set the updated plans collection to the view
//There has to be a better way!!
if( ! this.plans )
{
this.plans = new Plans();
this.plans.fetch({
success: function()
{
self.plansListView = new PlansListView({ collection : self.plans });
$( '#container' ).append( self.plansListView.render().el );
if( self.requestedID ) self.planDetails( self.requestedID );
}
});
}
else
{
this.plansListView = new PlansListView({ collection : this.plans });
$( '#container' ).append( self.plansListView.render().el );
if( this.requestedID ) self.planDetails( this.requestedID );
}
},
New Plan Route:
newPlan : function()
{ var plan = new Plan({name: 'Cool Plan', date: 'Monday', desc: 'This is a great app'});
this.newPlan = new NewPlanView({ model : plan, collection: this.plans });
this.newPlan.render();
}
完整代码(function($){
var Plan = Backbone.Model.extend({
defaults: {
name : '',
date : '',
desc : ''
}
});
var Plans = Backbone.Collection.extend({
model : Plan,
url : '/data/'
});
$( document ).ready(function( e ){
var PlansListView = Backbone.View.extend({
tagName : 'ul',
initialize : function()
{
_.bindAll( this, 'render', 'close' );
//reset the view if the collection is reset
this.collection.bind( 'reset', this.render , this );
},
render : function()
{
_.each( this.collection.models, function( plan ){
$( this.el ).append( new PlansListItemView({ model: plan }).render().el );
}, this );
return this;
},
close : function()
{
$( this.el ).unbind();
$( this.el ).remove();
}
});//end
var PlansListItemView = Backbone.View.extend({
tagName : 'li',
template : _.template( $( '#list-item-template' ).html() ),
events :{
'click a' : 'listInfo'
},
render : function()
{
$( this.el ).html( this.template( this.model.toJSON() ) );
return this;
},
listInfo : function( event )
{
}
});//end
var PlanView = Backbone.View.extend({
tagName : 'section',
events : {
'click button.add-plan' : 'newPlan'
},
template: _.template( $( '#plan-template' ).html() ),
initialize: function()
{
_.bindAll( this, 'render', 'close', 'newPlan' );
},
render : function()
{
$( '#container' ).append( $( this.el ).html( this.template( this.model.toJSON() ) ) );
return this;
},
newPlan : function( event )
{
app.navigate( 'newplan', true );
},
close : function()
{
$( this.el ).unbind();
$( this.el ).remove();
}
});//end
var NewPlanView = Backbone.View.extend({
tagName : 'section',
template : _.template( $( '#plan-form-template' ).html() ),
events : {
'click button.save' : 'savePlan',
'click button.cancel' : 'cancel'
},
intialize: function()
{
_.bindAll( this, 'render', 'save', 'cancel' );
},
render : function()
{
$( '#container' ).append( $( this.el ).html(this.template( this.model.toJSON() )) );
return this;
},
savePlan : function( event )
{
this.model.set({
name : 'bad plan',
date : 'friday',
desc : 'blah',
id : Math.floor(Math.random()*11),
total_stops : '2'
});
this.collection.add( this.model );
app.navigate('', true );
event.preventDefault();
},
cancel : function(){}
});
var AppRouter = Backbone.Router.extend({
container : $( '#container' ),
routes : {
'' : 'index',
'viewplan/:id' : 'planDetails',
'newplan' : 'newPlan'
},
initialize: function(){
},
index : function()
{
this.container.empty();
var self = this;
//This is a hack to get this to work
//on default page load fetch all plans from the server
//if the page has loaded ( this.plans is defined) set the updated plans collection to the view
//There has to be a better way!!
if( ! this.plans )
{
this.plans = new Plans();
this.plans.fetch({
success: function()
{
self.plansListView = new PlansListView({ collection : self.plans });
$( '#container' ).append( self.plansListView.render().el );
if( self.requestedID ) self.planDetails( self.requestedID );
}
});
}
else
{
this.plansListView = new PlansListView({ collection : this.plans });
$( '#container' ).append( self.plansListView.render().el );
if( this.requestedID ) self.planDetails( this.requestedID );
}
},
planDetails : function( id )
{
if( this.plans )
{
this.plansListView.close();
this.plan = this.plans.get( id );
if( this.planView ) this.planView.close();
this.planView = new PlanView({ model : this.plan });
this.planView.render();
}
else{
this.requestedID = id;
this.index();
}
if( ! this.plans ) this.index();
},
newPlan : function()
{ var plan = new Plan({name: 'Cool Plan', date: 'Monday', desc: 'This is a great app'});
this.newPlan = new NewPlanView({ model : plan, collection: this.plans });
this.newPlan.render();
}
});
var app = new AppRouter();
Backbone.history.start();
});
})( jQuery );
您是否每次点击索引页时都要获取数据,因为您希望列表与数据库同步(即其他人添加了一个项目,您希望它反映)?
如果这是不是的情况,你所做的对我来说似乎很好;只有当数据不存在时才进行抓取。
但是,如果确实希望列表同步;但你仍然希望你的新增加的项目呈现在其中;您可以从获取的列表中合并或使用另一个列表来保存新添加的数据。
如果你使用另一个列表,你只需要呈现两个列表;未保存的列表可能存在于持久化列表的顶部或底部,并分组在一起。
我认为你正在寻找"remove"参数,它将防止模型在获取期间从集合中删除。
this.plans.fetch({remove: false})
有关fetch方法的详细信息,请参阅主干文档。
相关文章:
- 在指令控制器中使用$attrs时出现问题
- 将PHP变量传递给jQuery时遇到问题
- Canvas Html5绘图应用程序,移动画布会导致重大问题
- 参数变量出现ngTable指令问题
- 使用模板事件侦听器删除 Meteor.js 集合时出现问题
- 关系问题-Mongo集合和MeteorJS
- 主干模型/集合中的Javascript范围界定问题
- 正在从集合[性能/最佳实践/问题]中的数组中删除对象
- 将用户发布到其他集合时出现问题
- 添加模型到集合问题
- 分离“骨干”集合(事件问题)
- 通过模板事件向集合插入数据:安全问题和必要的回调
- Meteor Users集合和Deps.自动运行的问题
- 关于骨干网和集合的问题以及增加的机制
- 在集合中引用变量时出现问题.方法在渲染函数中
- 流星关于改变视图和把数组集合的问题
- JavaScript .children循环时的HTML集合长度问题
- 在id为的主干集合中获取问题
- 对于js中的of语句-dom集合的问题
- 问题在创建另一个集合从一个mongodb查询的结果在节点