This thread started a discussion of how to do inverted templates in donejs.
Inverted templates (I think they are layouts in Ruby on Rails) allow “child” components/views/etc to alter the structure of parent components/view/etc.
For example, we might have components for different parts of the page. A home, blog and product component. We’d like to build these components to include the view for the main content (<article>
) of the page, the <head>
element of the page, and perhaps even a sidebar <nav>
.
The chat discusses a variety of ways to do it.
Not doing it by having all the configuration in the appVM
<html>
<head>{{content.head(this)}}</head>
<body>{{content.body(this)}}</body>
</html>
"404": {
head: stache(`<title>404</title>`),
body: stache(`<h1>uh oh</h1>`)
},
"200": {
head: stache(`<title>My Cool Site</title>`),
body: stache(`<h1>Hello World</h1>`)
}
}
DefineMap.extend({
get content(){
if( IS_200 ) { return contents["200"] }
else { return contents["400"] }
}
})
Pros: simple
Cons: doesn’t progressively load, components are not being used
Add a headView
to component’s prototype and read it:
All page components would look something like:
Component.extend({
tag: "blog-page",
view: `<articles> .... </articles>`,
headView: stache(`<title>Blog</title>`),
ViewModel: {...}
})
index.stache would call out to a pageComponentHeadView
with the pageComponentViewModel
:
<head>
{{ pageComponentHeadView(pageComponentViewModel) }}
</head>
<body>
{{pageComponentPromise.value}}
</body>
The appVM would get these properties:
get pageComponentPromise() {
return steal.import( .... ).then(()=>{ new Component })
},
pageComponent: {
get(lastValue, resolve){
this.pageComponentPromise.then(resolve)
}
}
get pageComponentHeadView() {
return this.pageComponent && this.pageComponent.headView
},
get pageComponentViewModel() {
return this.pageComponent && this.pageComponent.viewModel
},