13

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?

roman
  • 892
  • 9
  • 26
  • Please refer to http://stackoverflow.com/questions/30282377/how-can-i-yield-multiple-pieces-of-content-into-an-ember-js-component-template for a solution in ember v1.10. – aceofspades May 17 '15 at 01:28

1 Answers1

4

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:

  • In your app/components directory add your data-table.js file
  • In your app/templates/components directory add your data-table.hbs file
  • In your app/helpers directory add a file for custom views called custom_views.js

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!

alalani
  • 507
  • 4
  • 13