Search code examples
javascriptjsonrelationjsrenderjsviews

linking data from different json objects in jsrender


I am trying to link the data from foos and selectedFoos. I wish to list the selectedFoos and show the name from the foos object. The fooid in the selectedFoos would be linked to the foos id.

EDIT: I dont want to alter the structure of foos or selectedFoos.

fiddle is here

Html, Template

<div id="content"></div>
<script id="content_gen" type="x-jsrender">
    <ul> {^{for sf}} 
         <li > {{: fooid}} - {{: code}} {{foo.name}} </li>   
         {{/for}} 
    </ul>
</script>

JS

var foos = [{
    "id": 1,
        "name": "a"
}, {
    "id": 2,
        "name": "b"
}, {
    "id": 3,
        "name": "c"
}];
var selectedFoos = [{
    "fooid": 1,
        "code": "z"
}, {
    "fooid": 3,
        "code": "w"
}];

var app = {
    sf: selectedFoos,
    f: foos
};
var templ = $.templates("#content_gen");
templ.link("#content", app);

Solution

  • Scott's answer is nice. But since you are using JsViews - you may want to data-link so you bind to the name and code values. Interesting case here, where you want to bind while in effect traversing a lookup...

    So there are several possible approaches. Here is a jsfiddle: http://jsfiddle.net/BorisMoore/7Jwrd/2/ that takes a modified version of Scott's fiddle, with a slightly simplified converter approach, but in addition shows using nested {{for}} loops, as well as two different examples of using helper functions.

    You can modify the name or the code, and see how the update works. You'll see that code updates in all cases, but to get the name to update is more tricky given the lookup.

    You'll see that in the following two approaches, even the data-binding to the name works too.

    Nested for loops

    Template:

    {^{for sf }}
        {^{for ~root.f ~fooid=fooid ~sf=#data}}
            {{if id === ~fooid}}
                <li>{^{:name}} - {^{:~sf.code}} </li>
            {{/if}}
        {{/for}}
    {{/for}}
    

    Helper returning the lookup object

    Helper:

    function getFoo(fooid) {
        var r = $.grep(foos, function (o) {
            return o.id == fooid;
        })
        return r[0] || {name: ""};
    }
    

    Template:

    {^{for sf}}
        <li>{^{:~getFoo(fooid).name}} - {^{:code}} </li>
    {{/for}}
    

    See the many topics and samples here

    such as the following: