KO Delayed Update
by plus5keen
HTML
<table>
<thead></thead>
<tbody>
<tr>
<th>a</th>
<td data-bind="text: a"></td>
</tr>
<tr>
<th>b</th>
<td data-bind="text: b"></td>
</tr>
<tr>
<th>c</th>
<td data-bind="text: c"></td>
</tr>
<tr>
<th>d</th>
<td data-bind="text: d"></td>
</tr>
<tr>
<th>d Test</th>
<td>
<input data-bind="checked: dTest" type="checkbox" disabled></input>
</td>
</tr>
</tbody>
</table>
<button data-bind="click: updateAToRandomLetter">Update `a` to a Random Letter</button>
JavaScript
// Assume:
// `b` updates at an unknown time after `a` updates.
// `c` updates immediately when `a` updates.
// `d` must not update until `b` has come up-to-date, even though `c` updates.
// We cannot change the implementation of `d`. (Or can we? (What kind of *assumption* ends with "Or can we?"))
// (refer to A,B0,B1,B,C,D graph for initial concept)
var a = ko.observable('a ');
// `b` updates on a delay.
var _b = ko.observable();
var _bUpdate = ko.computed(function () {
return [a(), 'b '].join('');
});
var _bDelay = ko.computed(function () {
var bValue = _bUpdate();
setTimeout(function () {
_b(bValue);
}, 3000);
});
var _c = ko.observable();
var _cUpdate = ko.computed(function () {
return [a(), 'c '].join('');
});
var _lastBValue = _b();
var b = ko.computed(function () {
var bValue = _b();
if (bValue === _lastBValue) {
return bValue;
}
_lastBValue = bValue;
_c(_cUpdate());
return bValue;
});
var c = ko.computed(function () {
return _c();
});
var d = ko.computed(function () {
return [b(), c(), 'd '].join('');
});
var dTest = ko.computed(function () {
var dValue = d();
return dValue[0] === dValue[4];
});
var charCodeSmallA = 'a'.charCodeAt(0);
var getRandomLetter = function () {
return String.fromCharCode(charCodeSmallA + Math.floor(Math.random() * 26));
};
var updateAToRandomLetter = function () {
a(getRandomLetter() + ' ');
};
ko.applyBindings({
a: a,
b: b,
c: c,
d: d,
dTest: dTest,
updateAToRandomLetter: updateAToRandomLetter
});