问题
Let's say I have a list of Product entities. Then I want to edit one of these products, so I'm going to call getEntityByKey to get it from the cache.
However on the edit screen, it is likely that I'm going to display more properties than in the grid, and in my case I actually need to do an expand() on some of the Product properties.
So how do I handle that regarding caching ? If I use getEntityByKey, it's not going to do the expand(). I could execute a query, but then I don't take advantage of cached entities (in case I had already edited the Product before).
What strategy should I opt for in this case ?
回答1:
Another approach: add an isReadyForEdit
flag to your Product
entity. If false, you use a regular query to fetch the full Product
WITH EXPAND to get the related entities. If it's true, you know you have everything you need in cache and getEntityByKey
is all you need (because the related entities will be in cache as well). Make sure you return a promise in either case so that your caller logic is prepared to wait. This is the same technique as isPartial
in John Papa's examples.
Update Dec 17
Forgot to mention that, unlike in John Papa's example, your isReadyForEdit
should not be an unmapped property unless you need to serialize its state (and even then I'm not so sure). Just add the property to the entity when its true.
Not saying that what JP did was wrong; it fit his offline scenarios. But unmapped property adds unnecessary complexity if you don't need the Breeze-aware features
回答2:
One option that I often use is to create a navigation property of some type and then just materialize that from a call to the server. This will allow you to pull in the current properties of an entity and then when the navigation property materializes it will show up. Crude example -
In your JavaScript somewhere (assuming KO here, so in the view model)
var thisPerson = ko.observable();
// Set this person equal to the person returned from a call from cache
thisPerson(datacontext.getPersonById(1));
// Call to the server to get this persons boss
datacontext.getPersonsBoss(thisPerson);
And in the view
<div data-bind="with: thisPerson">
// Bind to properties of this person
<div data-bind="with: boss">
// Bind to the properties of a boss
// which is a navigation property of thisPerson
</div>
</div>
Basically what is happening is you get the person from cache, and then go get the person's boss from the server. Since person
has a navigation property to a boss
, then once the boss is returned and placed into cache by Breeze, it will materialize automatically in your view.
回答3:
Just one thing I noticed when applying Ward's suggestion above (for those who also need this solution, and in case you experience the same issue)...
When running a standard query, remember that data.results
returned from the query is an array. Therefore, if you want to return the entitiy itself, you'll need to extract it from the array.
i.e, on success
function succeeded(data) {
var result = data.results;
var entity = result[0];
...
return entity;
}
来源:https://stackoverflow.com/questions/20541415/breezejs-getentitybykey-with-expand