I'm trying to create an ember.js component which contains multiple content sections. The intuitive way to express the desire is to use semantic sub-components which will later be rendered in appropriate places so that, e.g.
{{data-table …}}
{{column name="Name" … }}}
item.name
{{/column}}
...
{{/data-table}}
will transform to
<table …>
<thead>
<th>Name</th>
...
</thead>
<tbody>
<tr>
<td>First item name</td>
…
</tr>
...
</tbody>
</table>
Is it possible to implement such constructs in handlebars.js or ember.js, e.g. via handlebars helpers? If so than how?
The natural use for {{yield}} is to decorate a template block with some HTML. Note that, using this trick, you can pass multiple blocks into a component and yield them in different parts of the component's HTML.
Here is the explanation: {{outlet}} -> This will provide a stub/hook/point into which you can render Components(Controller + View). One would use this with the render method of routes. In your case you will likely have a details route which could look like this.
One way to solve this is to use multiple handlebars helpers for each of the 'sub-components' that you want.
So here is the way I would structure the app:
Wherever you call your component, you can pass it parameters, these are probably from your model/controller, something along the lines of:
{{ data-table items=itemsArrayFromController }}
Now the variable itemsArrayFromController will be available to your components scope (ie in both the data-table.js file and data-table.hbs file)
In your data-table.js file you can also specify additional variables that your component has access to, so you might want to do something like:
App.DataTableComponent = Ember.Component.extend({
headers: ['Name', 'Some other Property']
});
Then in your data-table.hbs file you can render the html for your component and use helpers to render specific parts of the component:
<table>
{{ dataTableHeaderHelper headers }}
<tbody>
{{#each itemsArrayFromController }}
{{ dataTableRowsHelper item }}
{{/each }}
</tbody>
</table>
So here we are using the dataTableHeaderHelper to render the table header and then we loop through each item from the items array and render a row for it.
The actual table is then generated from within your helpers. So in your custom_views.js folder you can do the following:
// Returns the html for a table header
Ember.Handlebars.helper('dataTableHeaderHelper' function(headers) {
var html = "<thead><tr>";
for (var i = 0; i < headers.length; i++) {
html += "<th>" + Handlebars.Utils.escapeExpression(header[i]) + "</th>";
}
var html += "</tr></thead>";
return new Handlebars.Safestring(html);
});
// Returns the HTML for a table row
Ember.Handlebars.helper('dataTableRowsHelper' function(rows) {
// Okay I think you get the hang of it, loop through each row
// and then for each item generate the table row HTML
});
This should work for you!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With