问题
When calling ko.toJS(entity)
on any Breeze entity that has navigation properties or is part of a large object graph IE7-8 complain of long running script errors and even chrome can get bogged down for over 1 second.
What gives?!?
回答1:
I have had this plague me before and seen various forums or Github issues where this became an issue for devs. I wanted to share some knowledge in hopes that it helps others.
The problem
Breeze.js provides your client-side libraries or frameworks with an object graph. Calling JSON.stringify() on the entity will cause the dreaded stack overflow because some of the properties reference each other. Example -
Person -> Company -> Persons
Since a person has a navigation property of company that also has a navigation property of persons they continue to find each other.
ko.toJS() gets around this by detecting duplicates and stopping the serialization at that point.
Why is it slow?
The serialization takes longer depending on the number of entities in the object graph. Don't believe me? Load your app and call ko.toJS() then go load up a bunch more entities in the same object graph. It will take longer, guaranteed. The problem is that even if you call ko.toJS() on a single person Knockout isn't finding duplicates until it has serialized every person in the original persons company. This isn't a problem of Knockout nor Breeze - it is caused by how well interconnected everything is.
What can I do to fix it?
Using a projection query is the best solution, if you can. The problem is usually we need deeper nested levels of entities, not just the current entity. If your entity has a navigation property that has many related entities there is no easy way to perform a projection query, so we need to take it a step further in one of two manners -
Write a custom serializer
Vote for IdeaBlade (the company behind Breeze.js) to support unwrapping more efficiently
My opinion - expose a method on the entity manager to 'unwrap' that accepts the following parameters -
entityManager.unwrap(entity || [entities], [addtlTypesToUnwrap])
Where addtlTypesToUnwrap is either an array of strings or comma separated strings that define which related entity types to unwrap.
Example usage -
var thisEntity = manager.fetchEntityByKey('Person', 1, true);
var relatedProps = ['Company', 'Address']
entityManager.unwrap(thisEntity, relatedProps);
Which would unwrap Person, their address, their company, and the companies address (if it existed)
来源:https://stackoverflow.com/questions/22550560/calling-ko-tojs-on-breeze-entity-causes-slow-long-running-script