Backbone.js Hinzufügen von Modell-Sammlung Ausgabe
Baue ich eine test-Anwendung in Backbone.js (meine erste app mit Rückgrat). Die app geht so:
- Laden der Daten vom server "Pläne"
- Bauen, die Liste der Pläne und zeigen Sie auf dem Bildschirm
- Gibt es eine Schaltfläche hinzufügen, um einen neuen plan
- Sobald neue plan Hinzugefügt wird, fügen Sie der Sammlung ( nicht auf server speichern als jetzt )
- redirect auf index-Seite und zeigen die neue Kollektion ( umfasst der plan, den Sie gerade Hinzugefügt haben)
Mein Problem ist mit Punkt 5. Wenn ich speichern Sie eine plan, füge ich das Modell, um die Sammlung dann-redirect auf die ursprüngliche Ansicht. An diesem Punkt Hole ich meine Daten vom server. Wenn ich das Holen von Daten von dem server, dieser überschreibt meine Sammlung und meine hinzugefügten Modell ist Weg.
Wie kann ich das verhindern? Ich habe einen Weg gefunden, dies zu tun, aber es ist definitiv nicht der richtige Weg, bei allen. Unten finden Sie meine code-Beispiele dafür. Vielen Dank für die Hilfe.
PlansListView Anzeigen:
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 Save-Methode
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(){}
});
Router (Standard-Methode):
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 );
}
},
Neue Route Planen:
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();
}
VOLLSTÄNDIGE CODE
( 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 );
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sind Sie das abrufen der Daten zu jeder Zeit, die Sie auf der index-Seite, weil Sie möchten, dass die Liste in sync mit der Datenbank (d.h. jemand anderes Hinzugefügt ein Element, und Sie wollen es wider)?
Wenn das nicht der Fall, was Sie tun, scheint gut zu mir; Sie sind nur abrufen, wenn die Daten nicht vorhanden ist.
Wenn du allerdings tun möchten, die Liste zu synchronisieren, aber Sie immer noch wollen, um Ihre neu hinzugefügten Elemente gerendert unter Ihnen; Sie können entweder den Seriendruck aus der abgerufenen Liste aus oder verwenden Sie eine andere Liste zu halten, werden die neu hinzugefügten Daten.
Wenn Sie eine andere Liste, man muss Sie nur machen sowohl die Liste; nicht gespeicherte Liste sollte wohl vorhanden sein, entweder an der Oberseite oder der Unterseite des permanenten Liste gruppiert.
Ich denke, Sie sind auf der Suche für die "entfernen" - parameter, es wird verhindert, dass Modelle, die aus der Sammlung entfernt, während eine zu Holen.
Sehen die backbone-Dokumentation für weitere Informationen über die fetch-Methode.