I want to dynamically compile (and then render) a HTMLBars template at runtime, on the client in Ember. How can I do this?
Since Ember 2.10 is now using Glimmer, things might be a bit tricky here. In order to compile a template, you need to include ember-template-compiler.js
to your application. I'd recommend using ember-browserify
and ember-source
.
In your controller, import the compiler as the following.
import Ember from 'ember';
import Compiler from 'npm:ember-source/dist/ember-template-compiler';
export default Ember.Controller.extend({
compileContent() {
const template = Compiler.compile(this.get('dynamicContent'));
Ember.TEMPLATES[`YOUR_TEMPLATE_NAME`] = template;
},
// we observe content changes here
contentDidUpdate: Ember.observer('dynamicContent', function() {
this.compileContent();
}),
});
As tested, your content can contain anything from Ember helpers to your custom components, even your action bindings.
e.g.
<ul>
<li>{{#link-to 'index'}}Home{{/link-to}}</li>
</ul>
<div {{action 'yourCustomAction'}}>
{{your-custom-component params=yourCustomParams model=model flag=true}}
</div>
Now, let's do the magic in your template by using {{partial}}
helper.
...
{{partial 'YOUR_TEMPLATE_NAME'}}
...
This method works in Ember 2.13 without deprecation warnings, it should work in future updates. Please note that Ember.TEMPLATES
is global variable and the engine seems to cache it somehow, so do not reassign new values to the existing one.
This answer is now out of date. Please see @poohoka's answer which I've accepted above.
Building off of Kingpin2K's answer to Compile template client side in ember using HTMLbars:
For some background, it might be useful to refer back to Compiling Templates with Ember 1.10. We'll still need to load ember-template-compiler.js
. Add
app.import('bower_components/ember/ember-template-compiler.js');
to your ember-cli-build.js
.
Then you can write a Component like this:
import Ember from 'ember';
export default Ember.Component.extend({
layout: Ember.computed(function() {
return Ember.HTMLBars.compile(
'{{foo-bar}} <span>' + 'hello' + '</span>'
);
}),
});
This solution will likely break in future relases of Ember, depending on how the Ember Template compilation process changes with the advent of Glimmer 2.
Since Ember 2.13+ (without bower by default) you need to add in your ember-cli-build.js:
app.import('vendor/ember/ember-template-compiler.js');
For Ember version prior to 2.10 you need to include it via bower
(also on ember-cli-build.js)
app.import('bower_components/ember/ember-template-compiler.js');
And on the code you need to:
Ember.TEMPLATES['mycompiledcode'] = Ember.HTMLBars.compile('{{foo-bar}} <span>' + 'hello' + '</span>');
In the hbs file call:
{{partial 'mycompiledcode'}}
Or you can make a component like this:
import Ember from 'ember';
export default Ember.Component.extend({
layout: Ember.computed(function() {
return Ember.HTMLBars.compile(
'{{foo-bar}} <span>' + 'hello' + '</span>'
);
}),
});
Based on solution of another answer https://stackoverflow.com/a/37345099/6505594
I'm currently on Ember-2.9.x and I brought in the latest handlebars with my bower.json
:
"handlebars": "^4.0.0"
And then added it via my ember-cli-build.js
file:
app.import('bower_components/handlebars/handlebars.js');
This has worked for my typeahead
component and I don't see any reason why this won't work when upgrading to Ember-2.10 with Glimmer2.
来源:https://stackoverflow.com/questions/37345098/dynamically-compile-a-htmlbars-template-at-runtime-in-ember