Lets say I have an array of widget objects on my controller and each widget object has member variable that is assigned the name of a component class. How can I get my temp
I tried this and it seems to work, but its just a lot of guesswork on my part:
Ember.Handlebars.registerHelper('renderComponent', function(componentPath, options) {
var component = Ember.Handlebars.get(this, componentPath, options),
helper = Ember.Handlebars.resolveHelper(options.data.view.container, component);
helper.call(this, options);
});
and you use it the same way:
{{#each widget in widgets}}
{{renderComponent widget.componentClass widget=widget}}
{{/each}}
If you are using Ember CLI and Coffeescript here is a version for that. Create the following file in app/helpers/render-component.coffee
:
renderComponent = (componentPath, options)->
helper = Ember.Handlebars.resolveHelper(options.data.view.container, componentPath)
helper.call this, options
`export { renderComponent }`
`export default Ember.Handlebars.makeBoundHelper(renderComponent)`
From there, you can call {{render-component "foo-bar"}}
from a template.
Since the Ember ecosystem is ever changing, here is the version I tested it on:
In Ember 1.11, the new component helper allows you to do this:
{{#each widget in widgets}}
{{component widget.componentClass}}
{{/each}}
As of today, Jan 19th, 2015, 1.11 is not a stable release but this feature is in the canary version.
Sounds like I've run into a lot of the same problems as you. All components are registered as top level helpers, which means you can do a similar method to the one you linked of creating a handlebars helper that does the lookup. Like this:
Ember.Handlebars.registerHelper('lookup', function(component, options) {
component = Ember.Handlebars.get(this, component, options);
Ember.Handlebars.helpers[component].call(this, options);
});
Then in your template:
{{#each widget in widgets}}
{{lookup widget.componentClass}}
{{/each}}
Here's a jsbin with a working example: http://jsbin.com/ucanam/2482/edit
Hope that helps!
For some reason, the new version of handlebars makes calling helpers from other helpers impossible. Instead you can lookup the template through the Ember.TEMPLATES
global. I've updated the JSBin to use this method.
You can also get the template via options.data.view.templateForName(component)
, but it feels a bit more brittle than Ember.TEMPLATES
.
It's changed again. Ember.Handlebars.resolveHelper
is now the correct way to do it. See @StrangeLooper's answer.