Stefano
Stefano

Reputation: 3259

Render knockout template only during ajax requests

I'm trying to use knockout for a fast template rendering of JSON data received from a request with jQuery.

Basically, I would load the page with already pre-rendered HTML content (so I can show the content, and if the user's browser has the javascript disabled, I don't pretend to have all the functions working but at least show the basic content).

The next time a user clicks the link, instead of reloading the page, I submit a get-request with Ajax and get some json back. That is the data I should render in the place of the old content.

The problem is really simple: I integrated the knockout template with my HTML markup but when the page loads after calling ko.applyBindings(myviewmodel) I get all the pre-rendered content removed. This is because my model doesn't have any item to render.

Is there a way to use pre-rendered data for HTML requests and knockout templating for Ajax requests only?

Upvotes: 1

Views: 1936

Answers (2)

Brett Postin
Brett Postin

Reputation: 11375

Instead of trying to do two separate things, can you not do the following:

  1. Define your viewmodel with an observable property that will hold the data for your content.
  2. On initial page load, initialise the observable property with your pre-rendered data (retrieved from a hidden field perhaps?).
  3. Bind your content element to the observable using your template.

Then when you make your ajax requests, just update the data in the observable property with the data retrieved from your request, and the UI should update automatically.

Edit:

Here's a quick jsFiddle demonstrating the concept (comment javascript out to simulate disabled javascript).

<input id="initialstate" type="hidden" value="4,5,6" />

<ul id="content" data-bind="template: { name: 'item-template', foreach:data }">
    <li>1</li>
    <li>2</li>
    <li>3</li>    
</ul>

<script type="text/html" id="item-template">
    <li data-bind="text: $data"></li>
</script>​

var viewModel = (function()
{
    var self = {};

    self.data = {};

    function init() {
        $('#content').empty(); 
        self.data = ko.observableArray($('#initialstate').val().split(','));
    }

    init();

    return self;
}());

ko.applyBindings(viewModel);

Upvotes: 0

Kyeotic
Kyeotic

Reputation: 19847

Here is a fiddle demonstrating how a visible binding can show/hide templates. Note that if you deselect Knockout from the list on the left, the Welcome section still shows up properly. Click the button to mimick an ajax request, and see the template section show up.

A visible binding is a standard Knockout binding that controls whether a control displays or not. It looks like this:

<div data-bind="visible: welcome">

Where welcome is an observable property on your viewmodel.

If this still isn't clear, I strongly recommend the Knockout Interactive Tutorials, they will cover this and other basic usage.

Upvotes: 3

Related Questions