Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a standard way of change tracking with a Knockout bound page?

I have a rather complex web page with various tabs, forms, radio buttons, drop downs, etc. It's all bound using Knockout.js to a very complex JavaScript object that was loaded via an AJAX call. Of course the user can muck with stuff to their heart's content, at which point they hit a Save button to persist all their changes back to the server.

I'm in the process of coming up with a good design to track exactly what was changed on the page so I can implement saving. So, I've come up with a few possible implementations.

Option 1) Just send everything back and let the server sort it out: With this method, I'd let Knockout just update the data source. The Save button would call .toJS() and send that data back to the server. Pros: It's super easy, and takes very little work on the client. Cons: The server doesn't really know what changed and has to either load the data from the database to compare, or just save all the fields again. These fields come from multiple tables and have complex relations. It also treats the entire document as a single atomic unit. If someone else changed Field A and you changed field B, one user is going to lose their change.

Option 2) Use JavaScript to compare the original data and the current data: Using this technique, when the user clicks on the Save button, I would systematically compare the original data and current data and generate a graph of changes. Pros: This would ideally result in a compact graph of exactly what the user changed, and could even no-op if nothing was changed. Cons: The data I'm binding to is complex. It consists of strings, arrays, objects, arrays of objects, arrays of objects with other objects, etc. Looking for changes would be a rather complex nested loop.

Option 3) Track changes as they are being made in the UI: I would have to observe changes as they happen, and keep a delta as UI elements were changed. The Save button would simply send that change graph to the server if it had any pending changes. Pros: No need to compare two huge JavaScript objects looking for changes, but still has all the benefits of option 2. Cons: Knockout doesn't appear to have a standard way to listen to all changes using a single event handler. I believe I would have to resort to binding to all the UI elements, or creating custom bindingHandlers in Knockout to implement this real-time change tracking.

My Question:

My question is mostly for Knockout.js experts. Is there a standard approach, or recommended guidelines to solving this obviously common scenario? Is sending back all the data, even stuff that hasn't changed, a common design? Or are people implementing custom change trackers? Does Knockout provide any sort of framework that eases this requirement?

Update: Found this thing, not sure if it could be useful or if anyone has any feedback on it.

like image 449
Mike Christensen Avatar asked Feb 18 '13 22:02

Mike Christensen


2 Answers

If it's a question of enabling/disabling the Save button, allowing the user to navigate "from" that page/state, then you can check with the https://github.com/CodeSeven/kolite

check the knockout.dirtyFlag.js

Hope this helps.

Edit: remember that you should "never" trust the data coming from the "UI". The real comparison and validation, ultimately goes in your "controlled" environment within the server.

like image 149
Patrice Calvé Avatar answered Oct 06 '22 19:10

Patrice Calvé


What I would probably do is take option 2 - the comparison itself can be as simple as stringifying the JS object and comparing it with a cached version of itself.

A few other options are discussed here.

P.S. Maybe ko.mapping can help you manage this monster of a JS object?

like image 23
Bragolgirith Avatar answered Oct 06 '22 19:10

Bragolgirith