Node array rendering.
ismail-codar opened this issue · comments
http://maquettejs.org/docs/component-approach.html is good. But looks components must be inside a container node. In real world otherwise true. For example: Bootstrap tab code has two nodes in level 0. ul and div.
<ul class="nav nav-tabs">
<li class="active"><a href="#home">Home</a></li>
<li class=""><a href="#profile">Profile</a></li>
</ul>
<div class="tab-content">
<div id="home" class="tab-pane fade active in">
<p>1</p>
</div>
<div id="profile" class="tab-pane fade">
<p>2</p>
</div>
</div>
We can utilize this within a fake div like h("div.fake", [h("ul.nav.nav-tabs", [..]), h("div .tab-content", [..])])
but it's annoying.
It would be a nice feature if renderMaquette functions can be return virtual node array.
You can get a renderMaquette function to return an array of VNodes. I've altered the input example found on the website to demonstrate: (http://codepen.io/anon/pen/rrozZo)
If you're doing this in typescript make sure the renderMaquette function's returnvalue is a VNode[].
document.addEventListener('DOMContentLoaded', function () {
var h = maquette.h;
var domNode = document.body;
var projector = maquette.createProjector();
var yourName = ''; // Piece of data
var createDoubleInput = (getName, inputHandler) => {
return {
renderMaquette: () => {
return [
h('input', {
type: 'text', placeholder: 'What is your name?',
value: getName(),
oninput: inputHandler
}),
h('input', {
type: 'text', placeholder: 'What is your name?',
value: getName(),
oninput: inputHandler
})
]
}
};
};
// Plain event handler
function handleNameInput(evt) {
yourName = evt.target.value;
}
// This function uses the 'hyperscript' notation to create the virtual DOM.
var doubleInput = createDoubleInput(() => yourName, handleNameInput);
function renderMaquette() {
return h('div', [
doubleInput.renderMaquette(),
h('p.output', ['Hello ' + (yourName || 'you') + '!'])
]);
}
projector.append(domNode, renderMaquette);
});`
I am trying to use maquettejs with a page router. Moving routers main section to inside application main renderMaquette function can fix my problem.
In the above example undermost renderMaquette function returns a container div not array.
My problem actually appending vnode arrays with projector. But another solition is possible
document.addEventListener('DOMContentLoaded', function () {
var h = maquette.h;
var domNode = document.body;
var projector = maquette.createProjector();
var createLinks = () => {
return {
renderMaquette: () => {
return [
h('a', {
href:"#/link1"
}, ["link1"]),
[" | "],
h('a', {
href:"#/link2"
}, ["link2"])
]
}
};
};
var createRouter = ()=> {
return {
renderMaquette: ()=> {
if(document.location.hash == "#/link1") {
return h("span", ["page 1"])
}
else if(document.location.hash == "#/link2") {
return [
h("span", {key:"page1"}, ["page"]),
h("span", {key:"page2"}, ["2"])
]
}
}
};
}
// This function uses the 'hyperscript' notation to create the virtual DOM.
var links = createLinks();
var router = createRouter();
function renderMaquette() {
return h('div', [
links.renderMaquette(),
h("hr"),
router.renderMaquette()
]);
}
projector.append(domNode, renderMaquette);
window.onhashchange = function (evt) {
projector.scheduleRender();
};
});
`
It looks like you can omit the extra 'div' by using projector.merge
instead of projector.append
in your code snippet above. See http://maquettejs.org/docs/typedoc/interfaces/_maquette_.projector.html#merge