Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Alright, I think I've found a way myself.</p> <p>Following code requires <a href="https://github.com/janl/mustache.js" rel="nofollow">mustachejs</a> and <a href="https://github.com/kriszyp/compose" rel="nofollow">composejs</a>:</p> <pre><code>var noop = function() {}; var templates = { secondTmpl: Mustache.compile("&lt;i&gt;Yet another template.. {{{outlet}}}Here's some text: {{text}}&lt;/i&gt; {{date}}"), template: Mustache.compile("&lt;b&gt;{{val}}&lt;/b&gt;&lt;p&gt;{{{outlet}}}&lt;/p&gt;&lt;ul&gt;{{#list}}&lt;li&gt;{{.}}&lt;/li&gt;{{/list}}&lt;/ul&gt; {{test}}") }; var tree = [ { view: "Main", template: "template", data: { val: "yup!!", list: [1, 2, 3, "Four", 5], test: function() { return new Date(); } }, children: [ { template: "secondTmpl", data: { text: "Some Value", date: function() { return new Date(); } } }, { view: "Test", template: "secondTmpl", data: { text: "ANOTHER TEMPLATE", date: function() { return new Date(); } }, children: [ { template: "template", data: { val: "Pretty nested template", list: [56, 52, 233, "afsdf", 785], test: "no datetime here" } } ] } ] } ]; var View = Compose(function(options) { Compose.call(this, options); this.el = document.createElement(this.tag); }, { tag: "div", render: function() { if(this.childViews) { this.data.outlet = "&lt;div class=\"outlet\"&gt;&lt;/div&gt;"; } this.el.innerHTML = this.template(this.data); this.didRender(); if(this.childViews) { var lastEl; this.childViews.forEach(function(view) { if(!lastEl) { var outlet = this.el.getElementsByClassName("outlet")[0]; lastEl = view.render().el; outlet.parentNode.replaceChild(lastEl, outlet); } else { var el = view.render().el; lastEl.parentNode.insertBefore(el, lastEl.nextSibling); lastEl = el; } }, this); } this.didRenderDescendants(); return this; }, didRender: noop, didRenderDescendants: noop }); var TestView = View.extend({ didRender: function() { var nodes = this.el.querySelectorAll("*"); for(var i = 0; i &lt; nodes.length;i++) nodes[i].style.border = "2px dotted red"; } }); var MainView = View.extend({ didRender: function() { var nodes = this.el.querySelectorAll("*"); for(var i = 0; i &lt; nodes.length;i++) nodes[i].style.backgroundColor = "lightgray"; } }); function traverse(node) { var viewOptions = { template: templates[node.template], data: node.data }; if(node.children) { viewOptions.childViews = node.children.map(function(n) { return traverse(n); }); } return node.view ? new window[node.view + "View"](viewOptions) : new View(viewOptions); } function init() { tree.forEach(function(node) { var view = traverse(node); window["view"] = view; document.body.appendChild(view.render().el); }); } window.onload = init; </code></pre> <p>The trick is to replace the div.outlet with the first child view instead of appending to it. Then it's a matter of inserting the other child views next to each other.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload