Anyone tackled unapplyBindings(Model) after applyBindings(Model)

280 views
Skip to first unread message

emmanu...@gmail.com

unread,
Aug 11, 2011, 10:45:25 AM8/11/11
to knock...@googlegroups.com
Hi Guys,
    Looks like KO doesn't come with an unapplyBinding method to undo bindings. I'm about to look into extending KO to do just that but I wanted to ask if someone already got to it first. If think its a great feature especially during edit when you might need to cancel and keep the initial values before edit. The idea is to unapplyBinding during edit and initiate applyBinding with forced direction(elements to observable) on save. I will also be more than happy to hear people ideas of other ways to accomplish edit with cancel option.

Mark Hahn

unread,
Aug 11, 2011, 1:49:30 PM8/11/11
to knock...@googlegroups.com
This may not match your problem, but I had a design problem where I was using a contenteditable attribute to allow editing a div container.  That div had a KO binding that would clobber the value while it was being edited.  I solved the problem by creating a custom binding that refused to replace the value when contenteditable was present.

emmanu...@gmail.com

unread,
Aug 11, 2011, 2:49:59 PM8/11/11
to knock...@googlegroups.com
That wont work since once the user starts editing, they cannot cancel out of the change they just made. I have seen solution where they keep two oberservables eg. saved:ko.observable(' '), edit:ko.observable(), where edit is using during edit mode and ones saved instigated after edit, the edit value is transferred into the saved value but seems a bit tedious. That means if you have a form with possibly 10 editable fields, you need 20 observables to support cancel.

rpn

unread,
Aug 11, 2011, 11:54:48 PM8/11/11
to knock...@googlegroups.com
Hello-
I listed some thoughts on some options for this accept/cancel scenario in this post.

A few options:
1- create a clone of your object for editing and broker the values back and forth between the real objects on edit/save.  On cancel just throw it away.  
2- create edit properties on your objects and copy the values to the real ones on commit.  As you noted this can add a lot of bloat to your view model.
3- In the post, I describe creating an extended observable that supports caching the edited value and committing/resetting the value.  Now, you can just define your properties as protectedObservables instead of observables.  Sample here: http://jsfiddle.net/rniemeyer/X9rRa/
4- Similar to #1 and based on #3, you could create a modified observable that supports cloning an object for editing and writing it back on commit.  Recently we were playing with that idea in this post.  Sample here: http://jsfiddle.net/rniemeyer/np4Ve/
5- I have been playing with a new method that is slightly simpler than above.  We can create a custom binding that is a wrapper to the value binding.  Instead of setting up events against the real observable, instead we substitute a writeable dependentObservable that intercepts the edits and puts them into a "tempValue" property on the observable itself.  On an accept, we loop through the properties and look for any "tempValue" sub-properties.  When we find a tempValue then we commit it to the real observable. Hope that makes sense.  It does slightly simplify the scenario.  In the UI we just use the "tempValue" binding instead of "value".  Sample here: http://jsfiddle.net/rniemeyer/mVPfw/   Could probably use a little more error checking in the binding.   

Hope these ideas help.  I think that they will ultimately work out better than trying to bind/unbind the UI.  I would be happy you get any of these ideas or other ideas that you have working for your scenario.

emmanu...@gmail.com

unread,
Aug 12, 2011, 11:53:47 AM8/12/11
to knock...@googlegroups.com
I like the protectedObservable solution better. Its more concise rather than actually placing temp value in the binding. A lot of this one off work around can be helped if a binding setup could return a binder object through which you could trigger bind programatically with direction (elem->observable or observable -> elem) or put the bind to sleep. Now, this is all thinking aloud but if knockout can behave similar to jquery validation with validator object, can call on valid etc. eg.

Model.binder = ko.applybinding(Model)
//with that, you could do
Model.binder.sleep(); // put all binding to sleep, thus changes to fields will not be pushed to observables and visa versa
Model.binder.wake(); // activate all binding, thus changes to fields will be pushed to observables and visa versa
Model.binder.bind(direction) // trigger binding in a particular direction - to_obersvable, to_dom

Thus, in edit mode, put the binder to sleep(), on cancel wake() the binder and on save wake().bind('to_obersvable')

Now, please don't crucify me. I don't know the inner workings of KO to decide if its doable or not but will like to put the solution out there for you guys to decide if its a good solution and if it can be done with minimal effort.
Reply all
Reply to author
Forward
0 new messages