Dynamically compile a HTMLBars template at runtime

2019-01-20 16:01发布

I want to dynamically compile (and then render) a HTMLBars template at runtime, on the client in Ember. How can I do this?

4条回答
成全新的幸福
2楼-- · 2019-01-20 16:23

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.

查看更多
你好瞎i
3楼-- · 2019-01-20 16:27

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.

查看更多
太酷不给撩
4楼-- · 2019-01-20 16:34

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

查看更多
我命由我不由天
5楼-- · 2019-01-20 16:45

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.

查看更多
登录 后发表回答