Скомпилировать строку шаблона Ember и запустить ее программно, без приложения Ember?

#javascript #ember.js #handlebars.js

#javascript #ember.js #handlebars.js

Вопрос:

Я просто хочу запустить строку шаблона для объекта и изучить результат

У меня есть строка, которая является шаблоном. Я «скомпилировал» его. Теперь я хочу запустить его против объекта и изучить результат.

Но это не работает:

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

То, что я хочу получить, — это результат DOM запуска моей скомпилированной строки для объекта. Другими словами, набор элементов DOM, который выглядит примерно так:

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

Похоже, что Ember.Handlebars.compile очень тесно связан с другими частями приложения Ember, до такой степени, что он ожидает, что многие вещи будут заполнены в контексте, который я передаю из скомпилированной функции. Мне еще предстоит выяснить, что это за вещи, или если есть лучший способ создать контекст для передачи в скомпилированную функцию.

Другие вещи:

  • Я не хочу использовать простые «не-Ember» рули.
  • Я бы хотел избежать создания приложения Ember, если смогу.
  • Я действительно не хочу отвечать на вопросы о том, «почему» я хочу это сделать. Это то, что я хочу сделать. : P

Ответ №1:

Почему вы хотите это сделать? 😉

Честно говоря, самый простой способ сделать это — создать представление. Ember подключает кучу причудливых материалов для рендеринга, когда вызывает compile из-за привязки данных и т. Д., Поэтому его сложно создать прямо из функции компиляции (он передает множество дополнительных материалов, таких как буферы и т. Д.)

 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');
  

Пример

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
});
  

или вы можете подключиться к обратному didInsertElement вызову

 var foo = view.create(blah);

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

foo.appendTo('#blah');
  

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

Привязки остаются в силе при создании шаблона Ember handlebars, поэтому вы можете изменить переданный объект, и он обновит шаблон.

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

Комментарии:

1. Это мне очень близко… однако DOM не обновляется до тех пор, пока не произойдет «что-то», что синхронизирует привязки. Я не уверен, как узнать, когда это происходит. Другими словами, если вы $('#blah').html() сразу проверите послесловие, оно будет пустым.

2. Похоже, мне нужно использовать Ember.run.next(function() { /*examine #blah here*/ }); для проверки результатов. Этот ответ подойдет.

3. Обновлен ответ, чтобы отразить дополнительную информацию

4. Вы также можете подключиться к асинхронному обратному вызову didInsertElement