Edit in JSFiddle

var fakeText = " - lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ut tempus lorem. Etiam laoreet volutpat viverra. Vestibulum non nunc eu justo adipiscing rhoncus et eget leo. Ut tincidunt, orci a tristique aliquet, ipsum leo rutrum nisi, ac scelerisque leo magna quis justo. In quis lacus a tortor lacinia euismod et ut lectus. Quisque suscipit iaculis lacus. Pellentesque varius volutpat lacus, ac semper arcu porttitor sit amet. In feugiat pharetra laoreet. Nam condimentum gravida suscipit. Pellentesque ac lectus nec elit aliquam lobortis in sit amet massa.";

//an observable that retrieves its value when first bound
ko.onDemandObservable = function(callback, target) {
    var _value = ko.observable();  //private observable

    var result = ko.computed({
        read: function() {
            //if it has not been loaded, execute the supplied function
            if (!result.loaded()) {
                callback.call(target);
            }
            //always return the current value
            return _value();
        },
        write: function(newValue) {
            //indicate that the value is now loaded and set it
            result.loaded(true);
            _value(newValue);
        },
        deferEvaluation: true  //do not evaluate immediately when created
    });

    //expose the current state, which can be bound against
    result.loaded = ko.observable();  
    //load it again
    result.refresh = function() {
        result.loaded(false);
    };

    return result;
};


function Tab(id, name) {
    this.id = id;
    this.name = ko.observable(name);
    //sample of using an on-demand observable here
    this.details = ko.onDemandObservable(this.getDetails, this);
}

Tab.prototype.getDetails = function() {
    $.ajax({
        type: 'POST',
        url: '/echo/json/',
        data: {
            json: ko.toJSON({
                details: new Date().toLocaleTimeString() + " " + this.name() + fakeText
            }),
            delay: 1
        },
        context: this,
        success: function(data) {
            this.details(data.details);
        },
        dataType: 'json'
    });
};

var viewModel = {
    tabs: ko.observableArray([
        new Tab(1, "Tab One"),
        new Tab(2, "Tab Two"),
        new Tab(3, "Tab Three")
        ]),
    selectedTab: ko.observable()
};

//select the first tab
viewModel.selectedTab(viewModel.tabs()[0]);
//suppose that we already loaded the first tab's details, we can set it directly to avoid the AJAX call
viewModel.tabs()[0].details(new Date().toLocaleTimeString() + " " + "Tab One" + fakeText);

ko.applyBindings(viewModel);
<ul class="nav nav-tabs" data-bind="foreach: tabs">
   <li data-bind="css: { active: $parent.selectedTab() === $data }">
       <a href="#" data-bind="text: name, click: $parent.selectedTab"></a>
    </li>
</ul>

<div class="tab-content" data-bind="with: selectedTab">
    <div class="tab-pane active">
        <img src="http://rniemeyer.github.com/KnockMeOut/Images/loading.gif" data-bind="visible: !details.loaded()"  />
        <a href="#" data-bind="visible: details.loaded, click: details.refresh">
            <img src="http://rniemeyer.github.com/KnockMeOut/Images/refresh.png" />
        </a>
        <span data-bind="text: details, css: { stale: !details.loaded() }"></span>  
    </div> 
</div>
img { margin: 2px; }
.stale { color: #ccc; }