How can I re-compile ember handlebars templates?
Example:
I have a url /page/:page_id
which returns json object. This object describes the page structure. Each page has different structure.
{page: {
id:2,
structure:[
{type: 'row', children:[...]},
{type: 'module', id: 42}
]
}
I have to dynamically change the template content according to the json object.
{{#row}}
{{#container}}
Inner text
{{/container}}
{{/row}}
{{#module id=42}}
And recompile it
Ember.TEMPLATES['page'] = Ember.Handlebars.compile(hbs)
It works only for the first time. So overwriting page
property in TEMPLATES
doesn’t affect.
In order to do what you’re asking, you would create a view class and update the template
property on the view. (Though, this means that you’re compiling templates in the browser…are you sure you want to do this?)
An example (supposing this is the PageDetail
route):
App.PageDetailView = Ember.View.extend({
template: Ember.Handlebars.compile(hbs),
updateTemplate: function() {
// Logic for creating a new template
this.set('template', Ember.Handelbars.compile(newHbs));
},
controllerModelDidChange: function() {
Em.run.once(this, 'updateTemplate');
}.observes('controller.model')
});
You can also manually the DOM with the View object using appendChild
and removeFromParent
, etc, that way you’re not having to build a string template that then gets compiled. Not sure what the performance tradeoffs there would be.
That being said, the way things have been going with Ember you might be better suited in building Helpers and Components that handle every possibility for the page structures. So, you might get something like:
{{#each structure}}
{{render-structure type=type}}
{{/each}}
I thought about helpers and components. How to be in case with children
{{#each structure}}
{{render-structure type=type}}
{{/each}}
What should be in render-structure compoent view code to render child in deep?
So, the render-structure
component could perhaps be recursive…
// PageDetail.hbs
{{#each item in structure}}
{{render-structure type=item.type data=item}}
{{/each}}
// components/renderStructure.hbs
{{...Other template content...}}
{{#each child in data.children}}
{{render-structure type=child.type data=child}}
{{/each}}
1 Like
I can’t find a way how to wrap children with element. Block - none, container - div, h2 - h2, module - component
"structure": [
{
"type": "block",
"name": "departments",
"children": [
{
"type": "container",
"children": [
{
"type": "h2",
"innerHtml": "Contact us today"
},
{
"type": "module",
"name": "ContactDepartment",
"theme": "responsive1",
"id": 1
},
]
}
]
}
]
I should get something like
{{#h2}}
{{innerHtml}}
{{#if data.children}}
{{#each child in data.children}}
{{render-structure type=child.type data=child}}
{{/each}}
{{/if}}
{{/h2}}
or
{{#module id=id theme=theme name=name}}
{{#if data.children}}
{{#each child in data.children}}
{{render-structure type=child.type data=child}}
{{/each}}
{{/if}}
{{/module}}