I like the idea of Peter Lyon. I have thought about this several times, but have not actually used it. However, for all the ways I dealt with, here are my two favorites:
- Values without attribute
- Browse Models
Values without attribute
It is simple: do not save the values that you need in the standard attributes of the model. Instead, attach it directly to the object:
myModel.someValue = "some value";
The big problem is that you are not getting all the events associated with calling set in the model. Therefore, I am inclined to this method, which does everything for me. For example, the general method that I put on the models is select to say that this model is selected:
MyModel = Backbone.Model.extend({ select: function(){ if (!this.selected){ this.selected = true; this.trigger("change:selected", this, this.selected); } } });
In your case, I'm not sure if this will be a good approach. You have data that should be calculated based on the values that are already in your attributes.
For this, I tend to use view models.
View models.
The basic idea is that you create a basic model that is saved as usual. But you come and create another model that inherits from your original, and adds all the data you need.
There are so many ways you can do this. Here is what could be a very simple version:
MyModel = Backbone.Model.Extend({ ... }); MyViewModel = function(model){ var viewModel = Object.create(model); viewModel.toJSON = function(){ var json = model.toJSON(); json.inches = json.mm / 25; return json; }; return viewModel; });
The big advantage of wrapping this with Object.create is that you now have a prototype inheritance situation, so all of your standard model functionality still exists. We just redefined the toJSON method in the view model so that it returns a JSON object with the inches attribute.
Then, in the view for which this is necessary, you must wrap your model in an initialization function:
MyView = Backbone.View.extend({ initialize: function(){ this.model = MyViewModel(this.model); },
render: function(){ var data = this.model.toJSON(); // returns with inches } });
code>
You can call new MyViewModel(this.model) if you want, but in the end do not change anything, because we explicitly return an instance of the object from the MyViewModel function.
When your view rendering method calls toJSON , you will get the inches attribute with it.
Of course, there are some memory and performance issues in this implementation, but they can be easily solved with some better code for the view model. This quick and dirty example should lead you to the next path.