Best way to get only modified rows from observableArray (when there is bulk edit option)
Asked Answered
G

2

5

I have an ObservableArray collection which binds to the HTML table with bulk edit option (MVC3), every time the user hits commit I wanted to send only the modified rows from the collection instead of sending entire viewmodel list, please advise if any best way to track or filter only the modified rows.

Galan answered 28/12, 2011 at 23:51 Comment(0)
H
15

Here is a post about creating a dirty flag in Knockout that will track changes to all observables in an object.

Typically, you would add a dirty flag to each item in your array in a constructor function or loop through each item and add the flag. Then, you can create a computed observable to represent just the changed items for sending back to the server.

Here is a sample that shows a dirty flag on each item and a computed observable that contains only the dirty items: http://jsfiddle.net/rniemeyer/wauwn/

Highlight answered 29/12, 2011 at 4:22 Comment(2)
your solution is perfect. Did you think of submitting this ko.dirtyFlag to the ko team ?Gyre
I am on the ko core team (just 3 people with Steve Sanderson the primary dev). The current thinking is generally to keep the core tight and to put things like this into plugins. I might consider putting this up as a proper project though.Highlight
S
2

It it not so trivial task as it may looks like.

At first, observable array only handles modification of array (insert, remove, reorder etc.) not modification of element.

At second, you would probably need special flag like 'isModified' in your model that binds to each table row.

Then you need to set that flag if some of the binding was updated. Knockoutjs observables provides method subscribe that allows to call your own function when observables is updated. Take a look at page http://knockoutjs.com/documentation/observables.html at the bottom there is a section called 'explicitly subscribe to observables'.

There is a quick draft of code that performs that task

function CreateArrayElementViewModel(inputData) {
     // Creating our view model
     var result = {
           prop : ko.observable(inputData.prop),
           val : ko.observable(inputData.val),
           isModified: false // This property would be true if entity was edited
     };     
     // Iterate over all properties and subscribe to knockoutjs observables
     for(prop in result) {
          if (typeof(result[prop].subscribe) != 'undefined') {
               result[prop].subscribe(function() { result.isModified = true; });
          }
     }

     return result;
}
Skydive answered 29/12, 2011 at 0:16 Comment(1)
Check that subscribe is a function to be sure, you are now only testing that a property exists. Test should be: result.hasOwnProperty(prop) && typeof result[prop] === "function"Nonesuch

© 2022 - 2024 — McMap. All rights reserved.