Sometimes you need to do uncommon things like rendering a template to a string. Before Ember Views were deprecated one could do the following to render a template to a string:
var controller = Ember.Controller.create({
name: 'templateToString'
});
var view = Ember.View.create({
template: template,
controller: controller,
container: container
});
view.createElement();
return view.element.innerHTML;
In Ember 2.0.0 there is no Ember.View anymore and 1-to-1 replacement of Ember.View with Ember.Component does not work because the way the rendering works was changed with Glimmer.
Nevertheles I have found a bit hacky solution for my use case which I would like to share. The following snippet defines a function that renders a template to a string. Unlike the previous method, it’s asynchronous and returns a promise:
// template-to-string.js
import Ember from 'ember';
// container is needed to have access to app helpers, components etc.
var container = null;
Ember.Application.instanceInitializer({
name: 'template-to-string',
initialize: function(instance) {
// grab the container using the instance initializer
container = instance.container;
}
});
// when you call this function
// app initialization must be finished
export default function(template) {
return new Ember.RSVP.Promise(function(resolve) {
// create a new component
var component = Ember.Component.create({
style: 'display:none;', // hide it
layout: template, // specify your template as a layout
container: container // provide container
});
// subscribing to didRender event
component.on('didRender', function() {
// no we can grab the result of rendering
var el = component.element.innerHTML;
// remove the component
this.remove();
resolve(el);
})
// append the component to the body to make it render
component.append();
})
}
Here is an example of using it:
// /some-route.js
import templateToString from 'ember-template-to-string';
model: function () {
// it accepts a pre-compiled template
return templateToString(Ember.TEMPLATES['my-template']).then(
function (tmpl) { // and returns a string via `tmpl` var
return {
templateAsString: tmpl
};
}
);
}
I am not sure if it’s the best solution or if it’s reliable but currently it works for me. Thanks for reading and post alternative solutions to the problem if you know some.