3
votes

I just want to run the template string against an object and examine the result

I have a string that is a template. I've "compiled" it. Now I want to run it against an object and examine the result.

But this doesn't work:

var template = '<div>{{#each items}}<div>{{item}}</div>{{/each}}</div>';
var compiled = Ember.Handlebars.compile(template);
var result = compiled({ items: [1, 2, 3] }); // ERRORS

What I want to get is the DOM result of running my compiled string against an object. In other words, a set of DOM elements that looks something like this:

<div>
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>

It appears that Ember.Handlebars.compile is very tightly coupled to other parts of an Ember application, to the point it expects a lot of things to be populated in the context I'm passing ot the compiled function. I have yet to figure out what all of these things are, or if there is a better way to create a context to pass to the compiled function.

Other things:

  • I don't want to use plain "non-Ember" Handlebars.
  • I'd like to avoid creating an Ember Application if I can.
  • I don't really want to answer questions about "why" I want to do this. This is what I want to do. :P
1

1 Answers

3
votes

Why do you want to do this? ;)

Honestly the easiest way to do this will be to create a view. Ember hooks up a bunch of fancy rendering stuff when it calls compile due to the data binding etc, so it's difficult to create it straight from the compile function (it passes in a slew of additional stuff, like buffers etc...)

var view = Ember.View.extend({
  template:Ember.Handlebars.compile('hello <div>{{#each item in view.items}}<div>{{item}}</div>{{/each}}</div>')
});

var foo = view.create({ items: [1, 2, 3] });

foo.appendTo('#blah');

Example

http://emberjs.jsbin.com/qeyenuyi/1/edit

// you must wait for all bindings to sync before you can check the contents of #blah:
var empty = $('#blah').html(); // this will be empty

Ember.run.next(function(){
  var notEmpty = $('#blah').html(); // this will have the proper result in it
});

or you can hook up to the didInsertElement callback

var foo = view.create(blah);

foo.didInsertElement = function(){
  console.log(foo.$().html());
}

foo.appendTo('#blah');

http://emberjs.jsbin.com/qeyenuyi/6/edit

The bindings are still in tact when you create a Ember handlebars template, so you can modify the object passed in and it will update the template.

http://emberjs.jsbin.com/qeyenuyi/2/edit