BorisMoore / jsviews

Interactive data-driven views, MVVM and MVP, built on top of JsRender templates
http://www.jsviews.com/#jsviews
MIT License
856 stars 130 forks source link

Dynamic content for a sub-template #363

Closed rtlehr closed 7 years ago

rtlehr commented 7 years ago

Hello, I'm new to jsView and I'm loving it, wish I had discovered it years ago. I have a question about sub templates. Is there a way to choose a dynamic file for the content of the sub template, for instance

Instead of doing this

<script id="movieTmpl" type="text/x-jsrender">
    <tr>
        <td>{{>title}}</td>
        <td>
            {{for languages tmpl="#languageTmpl"/}}
        </td>
    </tr>
</script>

<script id="languageTmpl" type="text/x-jsrender">
    <div>{{>name}}</div>
</script>

<script type="text/javascript">
var movie = {
    title: "Eyes Wide Shut",
    languages: [
        { name: "French" },
        { name: "Mandarin" },
        { name: "Spanish" }
    ]
};

$( "#movieList" ).html(
    $( "#movieTmpl" ).render( movie )
);
<script>

I could do something like (pseudo code)

<script id="movieTmpl" type="text/x-jsrender">
    <tr>
        <td>{{>title}}</td>
        <td>
            {{for languages tmpl="#languageTmpl"/}}
        </td>
    </tr>
</script>

<script id="languageTmpl" type="text/x-jsrender">
    <div>{{>name}}</div>
</script>

<script type="text/javascript">
var movie = {
    title: "Eyes Wide Shut",

        //PUT THE REFERENCE TO THE DATA FILE I WANT TO USE IN THE #languageTmpl HERE
    languages: ["languagesContent.js"]
};

$( "#movieList" ).html(
    $( "#movieTmpl" ).render( movie )
);
<script>

languagesContent.js

var languagesContent={ name: "French" ,
     name: "Mandarin"},
     name: "Spanish" }

I hope that makes since. Thanks for the help and this wonderful tool.

Ross

Paul-Martin commented 7 years ago

You would do that in your own javascript. Something like:

var movie = {
    title: "Eyes Wide Shut",

        //PUT THE REFERENCE TO THE DATA FILE I WANT TO USE IN THE #languageTmpl HERE
    languages: ["languagesContent.js"]
};

// load languages files
var done = movie.languages.map(function(language, i) {
  return $.getJSON(language).then(function(data) {
     // replace name of language file with language file content
     movies.languages[i] = data;
  });
});

// wait for all language files to be loaded, then render
$.when.apply(this, done).then(function() {
  $( "#movieList" ).html(
    $( "#movieTmpl" ).render( movie )
  );
});

Of course this is how you might do it with jsrender. If you are using jsviews you could something similar but do the loading / refreshing incrementally instead of waiting for all language files to be loaded.

Also I'm making the big assumption that you are doing this in the browser and not in node.

rtlehr commented 7 years ago

Thank you Paul. Yes, I'm doing this in the browser.

BorisMoore commented 7 years ago

You might like to look at compiled VMs and the merge feature that lets you download modified data and incrementally update the VM hierarchy. See for example http://www.jsviews.com/#jsvviewmodelsapi@mergesample.

Closing this issue for now.