I have a view model which has an observableArray of entities retrieved via Breeze.
// define the viewmodel
function episodesViewModel() {
this.episodes = ko.observableArray();
...
}
Each episode entity has a series of properties which I want populating in their entirety on page load. How can I then update only one of those properties on retrieval from and when saving back to the server? The other properties are much larger and will remain static so there's no point sending them back and forth over the wire.
Great question!
My first question to you is "are you sure that the payload weight of the extra 'static properties' is actually a problem?" I have to ask you ... as I would have to ask myself ... because I have a predilection for anticipating problems and solving them prematurely. After measuring I discover that all that work and worry really didn't matter for the application-in-the-field. Please forgive my impertinence.
Let us assume that you really do have a problem. The episode
object is extremely heavy (perhaps with image data) and you can't split it in your model into Episode
and EpisodeDetail
classes with a 1-to-1 relationship between them. You are stuck with one big, fat Epsiode
class. I know this happens. Just checking.
You can do what you desire. I want to make this scenario easier in Breeze. There is an "OK" way to do it today (some might call it a hack). I'll layout the outline of it for you here. You can try it ... and let us know how to refine it.
Create a DTO class (EpisodeSaveDto
?) on the server that represents the shape of the Episode
object you want to save. It must have the Id
and the properties you'd want to save.
It won't be part of the normal metadata coming from the server because it's not a real entity. So describe that DTO object in metadata in JavaScript on your BreezeJS client. Breeze will then treat your EpisodeSaveDto
as an entity. See the "NoDb" Sample for an example of this technique.
Create instances of EpisodeSaveDto
and populate them with your changes. You're updating, not adding new instances, so use the EntityState-setting signature on the createEntity
method.
var episode = manager.createEntity("EpisodeDto", { id: origEpisode.id, foo: changedFooValue }, EntityState.Modified);
On the server, in your custom (derived) EFContextProvider
, override the BeforeSaveEntities
method. This method receives a dictionary of changed entities, arranged by type.
Remove the collection of EpisodeSaveDto
changes and process them into appropriate Episode
entities for save. If you're not using EF or a SQL Db, than you'll be doing this in your implementation of ContextProvider
... again as shown in the "NoDb" Sample.
Add a collection of your ready-to-save Episode
entities to the dictionary of changed entities and attach them also to the EF context.
Breeze.NET on the server will save your manufactured Episode
entity on the server and ignore the incoming EpisodeSaveDto
(which it wouldn't know how to save anyway).
Confession: I'm writing this from memory and I'm a little fuzzy on step #6. I trust you get the idea. We're kind of faking Breeze.NET out.
As I said at the beginning, I'd like to make this scenario much easier. I'd like to see a built in support for "Commands" that can accept and return entity sets. Please add your vote to Breeze User Voice if this is something you think we should do.