JSFiddle - React, Tailwind, and code Playground
HTML
<button data-bind="click: switchToFirst">Select 1st tab</button>
<button data-bind="click: switchToSecond">Select 2nd tab</button>
<div data-bind="text: selectedTab().content"></div>
<div style="height: 30px"></div>
<button data-bind="click: selectItem">Select some item</button>
Current id: <span data-bind="text: itemId"></span>
JavaScript
var asyncComputed = function (evaluator, owner, options) {
var evalMissed = true;
var wasActive = false;
var result = ko.observable(), updateTrigger = ko.observable().extend({ notify: 'always' });
result.refresh = function () {
updateTrigger.valueHasMutated();
};
result.active = (options && typeof options.activeWhen == "function") ? options.activeWhen : function () { return true };
ko.computed(function () {
updateTrigger();
var isActive = result.active();
if (isActive && (wasActive === true || evalMissed === true)) {
evalMissed = false;
result(evaluator.call(owner)); // let's pretend it's always sync (for simplicity)
}
else {
// check if computed was triggered by "active" status change
if (isActive === wasActive)
evalMissed = true; // defer evaluation until will be active again
}
wasActive = isActive
});
return result;
};
var viewModel = new function(){
var self = this;
self.selectedTab = ko.observable();
self.itemId = ko.observable(0);
self.selectItem = function(){
self.itemId(self.itemId() + 1);
};
self.firstTab = new function(){
var tab = this;
tab.content = asyncComputed(function(){
alert("loading 1st tab content..."); return "1st tab content for id = " + this.itemId();
}, self, { activeWhen : function(){ return self.selectedTab() === tab }})
};
self.secondTab = new function(){
var tab = this;
tab.content = asyncComputed(function(){
alert("loading 2nd tab content..."); return "2nd tab content for id = " + this.itemId();
}, self, { activeWhen : function(){ return self.selectedTab() === tab }})
};
...