Repeatedly Render Dust.js Template with New Data

1.2k Views Asked by At

What would be the best way to go about repeatedly rendering a dust template while having it advance in the data file its referencing rather than just repeat from the start each time. For example:

Say I have a list of 100+ people stored as JSON in a variable called data:

{
    "people": [
        {
            "name": "Jerry",
            "age": "17"
        },
        {
            "name": "Darcy",
            "age": "19"
        },
        {
            "name": "Jacob",
            "age": "25"
        },
        ... and so on for 100 or so people
    ]
}

And I have this template.tl file that exports a row of three names/ages:

<div class="row">
    <div>{name} - {age}</div>
    <div>{name} - {age}</div>
    <div>{name} - {age}</div>
</div>

Which I precompile into template.js:

(function(){dust.register("template.tl",body_0);function body_0(chk,ctx){return chk.write("<div class=\"row\"><div>").reference(ctx.get(["name"], false),ctx,"h").write(" - ").reference(ctx.get(["age"], false),ctx,"h").write("</div><div>").reference(ctx.get(["name"], false),ctx,"h").write(" - ").reference(ctx.get(["age"], false),ctx,"h").write("</div><div>").reference(ctx.get(["name"], false),ctx,"h").write(" - ").reference(ctx.get(["age"], false),ctx,"h").write("</div></div>");}return body_0;})();

Then I have an index.html file that looks like:

<html>
    <head>
    ...
    </head>

    <body>
        <div id="people"></div>

        <button id="load-more" type="button">Load More</button>
    </body>

    <script src="js/dust-core.min.js"></script>
    <script src="js/template.js"></script>
</html>

What would be the best way to have it so each time the button is clicked, a row of three people would be appended inside the <div id="people"></div>, and each subsequent click would load the next three / test for the end of the data array (can assume the number of people is always a multiple of three for my needs).

1

There are 1 best solutions below

0
On BEST ANSWER

Change template.tl to:

<div class="row">
    {#.}
        <div>{.name} - {.age}</div>
    {/.}
</div>

There are 2 benefits to changing the template:

  • You can pass in any number of people objects, not just 3.
  • If you only have 2 elements left in the array, it will still render correctly.

JavaScript to perform the rendering:

$('#load-more').on('click', function(){
    var next3 = data.people.splice(0, 3);

    if(next3.length == 0){
        return; // Array is empty
    }

    dust.render('template.tl', next3, function(err, str){
        if(str){
            $('#people').append(str);
        }
    });
});

The most important part is data.people.splice(0, 3), this removes 3 elements from the array and returns them - See Array.prototype.splice().

The rest of the code is just JQuery to add an event listener and insert the rendered template.

JSFiddle