It would be possible to create the model on the first call to the server and then update it on the second call, but that sets up a slightly different workflow in several ways:
- If the user wants to abandon the creation in step (3) we need to delete the model, or inform the user that they need to do this.
- If operations are auditing this would be audited as a create and an update rather than simply a create.
- This wouldn't work at all if some values can only be set at creation time.
So I have gone with the two stage "get defaults, commit" process shown above.
This leads to a problem; when I parse the model returned from the server at step 2 as a Backbone Model I find that Model.isNew() returns false. This means that when I commit the model through a Model.save() an "update" operation occurs instead of a "create" Why is this? Let's look at the definition of isNew from backbone.js:
My model has the default value for idAttribute, "id". The id of my model on the server is a .NET
Guid, so when the server model is serialised to be returned in step 2 it will be serialised as:
As this model does have a value for "id", Model.has("id") will return true and Model.isNew() will return false.
Help is at hand though: when I define my model I can simply override the isNew() function:
Or alternatively if I'm going to use this behaviour throughout my application I can modify this behaviour on the Model prototype:
Either way, Backbone will now correctly distinguish between models that have been persisted and those that have not.
// A model is new if it has never been saved to the server, and lacks an id. isNew: function() { return !this.has(this.idAttribute); },
My model has the default value for idAttribute, "id". The id of my model on the server is a .NET
Guid, so when the server model is serialised to be returned in step 2 it will be serialised as:
{id: "00000000-0000-0000-0000-000000000000", title: null, anotherAtt: "Clever server logic set this"}
As this model does have a value for "id", Model.has("id") will return true and Model.isNew() will return false.
Help is at hand though: when I define my model I can simply override the isNew() function:
var MyModel = Backbone.Model.extend({ isNew: function() { return !this.has(this.idAttribute) || this.id === '00000000-0000-0000-0000-000000000000'; } });
Or alternatively if I'm going to use this behaviour throughout my application I can modify this behaviour on the Model prototype:
Backbone.Model.prototype.isNew = function () { return typeof this.attributes.id !== 'undefined' && this.attributes.id === '00000000-0000-0000-0000-000000000000'; };
Either way, Backbone will now correctly distinguish between models that have been persisted and those that have not.
No comments:
Post a Comment