Backbone JS Save/Delete to Server Keep Primary Keys Associated with Models?
Ok let's say I have a database with a Person table. It has the following fields.
Id (PK, auto-increment) Name (string) Age (int)
I can fetch the server for a List of People and when I render the Backbone Views it will have their associated Ids in the model. Great.
Now let's say I have an Add functionality to add a new Person. I might have 2 text boxes (one for name, one for age) and a save button.
When I click save I could use my People Collection from Backbone and add that record to the collection and it will also handle (POST to the Backbone Collection URL) posting (name, age) to my server.
However the thing I'm not understanding is the Id that is generated from the database insert is no longer associated with the Backbone Model I just spun up.
Or is the idea that after ever "add" I need to fetch again to 开发者_高级运维get a fresh list?
I may not have enough information to answer this based upon your question, so I'm presuming that you have a view that has been given a collection instance. Further, I'm presuming that your POST posts the model's attributes, but returns the model's attributes right back including its newly-assigned id.
So what you want to do is:
- Bind the view to the DOM event for whatever triggers the Person save.
- Bind the view to the collection instance's add (and/or remove events).
- In your Person save event handler, harvest the person attributes and initialize a new Person model with them; then save it. In your success callback, add the resulting model, which now has an id into the collection.
- In your add event handler, re-render the view as appropriate.
Here's some code:
PeopleView = Backbone.View.extend({
events: {
"submit form#person-form" : "onSave",
"click .remove-person" : "onRemovePerson",
},
// Presumes you've handed the view a people collection and
// named it 'collection' to enable backbone.js to auto set it
// into the view's state.
initialize: function(options) {
_.bindAll(this, "onPersonAdded");
this.collection.bind("add", this.onPersonAdded);
this.collection.bind("remove", this.onPersonRemoved);
},
onSave: function(e) {
var self = this;
var person = new Person();
var person_attrs = this.serialize(); // harvest from your form in this method.
person.save(person_attrs, {
success: function(saved_person, data) {
self.collection.add(saved_person);
},
error: function(aborted_person, response) {
// Error handling as needed.
}
});
},
onRemovePerson: function(e) {
e.preventDefault();
var cid = $(e.target).attr('id');
var person = this.collection.getByCid(cid);
person.destroy({
success: function(removed_person, data) {
self.collection.remove(removed_person);
},
error: function(aborted_person, response) {
// Error handling as needed.
}
});
},
onPersonAdded: function(added_person) {
// perform rendering as needed here.
},
onPersonRemoved: function(removed_person) {
// perform rendering as needed here.
}
});
As a stylistic note, you may not want to handle the model save code in the view. You could alternatively defer to a controller or some other appropriate entity.
精彩评论