I have a scenario where the data being manipulated on the client is presented and interacted with in a different way than it is represented on the server.
Consider t
You have some options:
Override toJSON
to return the computed duration
Create a duration()
method on the Backbone Model
. Only downside that you have to call it differently (obj.duration()
instead of obj.get('duration')
). In your view that hands obj.toJSON()
to your template, mix in the duration
attribute
Use https://github.com/asciidisco/Backbone.Mutators (or similar) to create a derived getter for duration
I am using a combination of the initialize() function together with change event listeners to update derived attributes. The idea is first to compute the attributes on model initialization, and second to let the model listen to its own changes and update the attributes accordingly.
My solution looks roughly like this:
MyModel: Backbone.Model.extend({
initialize: function() {
this.updateDerivedAttributes();
this.on('change:start_at', this.updateDerivedAttributes, this);
},
updateDerivedAttributes: function() {
this.set({
start_date: Utils.dateFromDate( this.get( "start_at" ) ),
start_time: Utils.timeFromDate( this.get( "start_at" ) ),
duration: Utils.youGetTheIdea()
}, {silent:true});
}
});
We are very used to send model.toJSON()
to feed the template. And this method is very tricky to overwrite because is used by other components.
But we can feed the template with a custom model.toJSONDecorated()
method that can look like this:
# in your Backbone.Model
toJSONDecorated: function(){
return
_.extend(
this.toJSON(),
{
start_date : Utils.dateFromDate( this.get( "start_at" ) ),
start_time : Utils.timeFromDate( this.get( "start_at" ) ),
duration : Utils.youGetTheIdea( :) )
}
);
}
Of course this is breaking a few patterns, I can live with it, if you don't you can move this logic to a Decorator
class as people have suggested in other answers.
Your model should correspond as closely as possible to what you have server side. So stick with start_at
and end_at
. That will greatly simplify your sync()
operations.
On your edit form's View, you can:
start_date
, start_time
, duration
through simple functions and call them in the template.start_at
and end_at
on submitting.