force value update on ko.observable()

10,876 views
Skip to first unread message

ljupce

unread,
Dec 1, 2011, 3:56:11 AM12/1/11
to KnockoutJS
Hi,

I'm developing web application which depends heavily on knockouts.js

In one "screen" i'm using jquery ui dialog box to add some data.
when the user hits add button popup dialog box is shown with 1 text
box. this text box is binded to some property in my view model.

When the user starts typing text into that text box and after that
hits close button on the dialog, view model is not updated because the
blur event did not fire on the text box.
Second time when dialog box is shown to the user the previous text
entered is still there.

I tried to update the view model in before dialog is shown but the
text is still there.
After some investigation in knockout.js i found this
function observable() {
if (arguments.length > 0) {
// Write
if ((!observable['equalityComparer']) || !
observable['equalityComparer'](_latestValue, arguments[0])) {
observable.valueWillMutate();
_latestValue = arguments[0];
observable.valueHasMutated();
}
return this; // Permits chained assignments
}
else {
// Read
ko.dependencyDetection.registerDependency(observable); //
The caller only needs to be notified of changes if they did a "read"
operation
return _latestValue;
}
}

which means that the value of observable is not updated with empty
value because _latestValue is empty.

so i changed function observable with this
function observable(newValue,forceWrite) {
if (arguments.length > 0) {
// Write

if(forceWrite){

observable.valueWillMutate();
_latestValue = arguments[0];
observable.valueHasMutated();
}
else{
// Ignore writes if the value hasn't changed
if ((!observable['equalityComparer']) || !
observable['equalityComparer'](_latestValue, arguments[0])) {
observable.valueWillMutate();
_latestValue = arguments[0];
observable.valueHasMutated();
}
}
return this; // Permits chained assignments
}
else {
// Read
ko.dependencyDetection.registerDependency(observable); //
The caller only needs to be notified of changes if they did a "read"
operation
return _latestValue;
}
}

in this way i can force value change even the _latestValue and new
value are same.

Is there any other way to force value update (without modificationn of
knockout.js ) ?

rpn

unread,
Dec 1, 2011, 9:18:13 AM12/1/11
to knock...@googlegroups.com
One option is to call myObservable.notifySubscribers(value), which will directly notify anyone interested in the value.  You would generally want to be careful with this, so that things don't get out-of-sync (value doesn't match myObservable()).

Alternatively, you could possibly force the field to blur in the close event and then still reset the value on the viewModel when it opens.



Michael Best

unread,
Dec 1, 2011, 2:52:27 PM12/1/11
to KnockoutJS
You could probably use the valueUpdate: 'afterkeydown' binding so that
the value is updated right away.

-- Michael

ljupce

unread,
Dec 9, 2011, 10:30:13 AM12/9/11
to KnockoutJS

Andrew

unread,
Aug 19, 2012, 9:13:45 PM8/19/12
to knock...@googlegroups.com
A "force" flag on observable update would be really useful here - see my suggestion at https://github.com/SteveSanderson/knockout/issues/610, e.g.:

myObservable("new value", /* force = */ true) 
Reply all
Reply to author
Forward
0 new messages