Dynamically compile a HTMLBars template at runtime in Ember

浪尽此生 提交于 2019-11-28 14:16:42

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!