-
Notifications
You must be signed in to change notification settings - Fork 440
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve deref for better MVC Integration #501
Comments
Forgot to mention that we will have to rev semver because this is a breaking change. I think it's the right decision. Old deref was really bad (my fault) and we're in preview mode. It's way too early to allow cruft to accululate on the API. @sdesai please provide feedback if anything here is unclear. |
@gdi2290 FYI |
sweet, yeah this would help for Angular 2 integrations 👍 I wouldn't worry too much about the versioning during developer preview
|
To be clear, the field is not |
Instead of devising a new JSON schema that augments a
As I work mostly in the |
@ggoodman your idea sounds more like what I had in mind. Each model could take a basePath argument. Any call to get or getValue would prepend the basePath before firing of the request. Deref would just mean returning a new model with the given path appended to the current base path. So deref looks like:
And you can do thing like:
Which would be equivalent to:
Am I understanding the purpose of deref correctly? |
@ewinslow you do understand @ggoodman the issue with your suggestion is performance. We have performance critical requirements as some of the devices we run on have low processing power. The performance overhead of creating these prototype style objects will simply cost to much. So a happy medium is a schema change where there are hidden objects on the output that hint This change was merged in #551 |
Currently deref has poor ergonomics for the following reasons:
The last issue is particularly problematic for UI integrations, because these integrations generally get a large block of data, distribute the JSON to component children, and also pass a deref'ed model to those Components that will later lazily load additional data. The issue is that component expansion is asynchronous in most MVC frameworks. This means that in between the get and deref call it is possible that the JSON Graph will have changed. As a result deref could be bound to different branch node than the one retrieved during get. This would cause a component to lazily load data from a different entity then it's eager load was retrieved from. At this puts the user interface into an inconsistent state.
At the moment the only solution is to deref all nodes immediately when the get call comes back, so that you have Models to dispense to Views in the event they need lazy loading. Obviously this is not efficient.
There is an elegant solution to the problem of deref:
To improve deref, we must first modify the get method to include a private “_path” property in the JSON whenever a reference is crossed. When a reference is not crossed, a reference to the parent node and the key at which to retrieve the current node at the parent node is set on the JSON branch node.
As an example, today get([“lolomo”,0,0,”item”,”name”]) returns this:
After this change, the same method would return this:
Now instead of deref accepting a deref Path and value paths, it accepts a branch node from the JSON.
If deref finds the hidden _path parameter, it immediately creates a new Model bound to the optimized path. If it finds the _key parameter, it follows the _parent up until it finds a _path key. Along the way it builds up a path suffix using the _key fields, and when it discovers a _path it concatenates the suffix to it and uses the new path as the deref path.
Deref is now synchronous, never has to make a round trip, and requires no value paths to preload. The changes to "get" also requires no new allocations. The cost of the additional property sets in get should be offset by the dramatic reduction in value gets during deref. Furthermore avoiding the creation of an Observable is also expected to save quite a bit of time.
At first the only valid input for deref will be branch nodes created during a get operation. All other inputs will throw. It is up to the developer to guard against passing null, undefined, or any of the other value types to deref.The one exception is reference. If a reference is passed to deref, the reference's target path will become the Model's deref'ed path. If we assume no dangling references, we should maintain the invariant we have today: deref only creates a Model once it verifies that the reference target exists.
The text was updated successfully, but these errors were encountered: