Как избежать обертывания шаблонов с помощью пустого div в Backbone?
Когда я создаю структуру представления, создается пустой div-контейнер, если el не установлен. Шаблон (this.$el.html(this.template(this.model.toJSON())))
, вставленный в этот div. Как избежать этой обертки? Мне нужен чистый шаблон без каких-либо оберток, чтобы я мог вставить его в любом месте, где захочу? Не разумно называть jobView.$e.children()
множеством элементов.
<script id="contactTemplate" type="text/html">
<div class="job">
<h1><%= title %>/<%= type %></h1>
<div><%= description %></div>
</div>
</script>
var JobView = Backbone.View.extend({
template:_.template($("#contactTemplate").html()),
initialize:function () {
this.render();
},
render:function () {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
var jobView = new JobView({
model:jobModel
});
console.log(jobView.el);
Ответы
Ответ 1
Я думаю, что реальный ответ на этот вопрос еще не представлен, просто удалите div
из шаблона и добавьте свойство className
в JobView
! Это приведет к необходимости разметки:
Шаблон:
<script id="contactTemplate" type="text/html">
<h1><%= title %>/<%= type %></h1>
<div><%= description %></div>
</script>
Вид:
var JobView = Backbone.View.extend({
className: 'job', // this class will be added to the wrapping div when you render the view
template:_.template($("#contactTemplate").html()),
initialize:function () {
this.render();
},
render:function () {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
Когда вы вызываете render
, вы получите нужную разметку:
<div class="job">
<h1><%= title %>/<%= type %></h1>
<div><%= description %></div>
</div>
Ответ 2
Я думаю, что лучшим решением для этого является:
render: function(){
var html = this.template(this.model.toJSON()));
var newElement = $(html)
this.$el.replaceWith(newElement);
this.setElement(newElement);
return this;
}
Ответ 3
Извините За поздний ответ, и это, возможно, уже было решено. Я нахожу все возможное, чтобы попытаться сделать шаблоны и представления как можно проще. Я использую Handlebars для своих шаблонов.
Каждый из ваших шаблонов, независимо от использования, должен иметь связанный с ними элемент HTML, поэтому в своем представлении выберите любые элементы, которые вы хотите, и удалите этот элемент из своего шаблона, вместо того, чтобы пытаться идти против зерна. Затем вы можете установить атрибуты в своем представлении, чтобы отразить атрибуты вашего удаленного элемента шаблона.
var yourview = Backbone.View.extend({
{
tagName : *whatever element ( i.e. section, div etc ),
attributes : {
id : 'your element id'
class : 'your element class'
etc
},
})
Затем в вашем шаблоне удалите этот элемент, этот элемент будет создан красиво, не обертывая ваш шаблон, вместо того, чтобы изменять метод рендеринга.
Ответ 4
Вы можете отобразить представление в любом контейнере, который вам нравится, либо указать свойство $el самостоятельно, либо использовать метод setElement()
перед вызовом render:
var jobView = new JobView({
model:jobModel
});
jobView.setElement($('#your_selector_here'));
console.log(jobView.el);
Если вы посмотрите на документы для View.el
, вы увидите, что вы также можете указать свойство el
либо при записи своего представления, либо путем передачи параметр в конструкторе.
Ответ 5
У меня была такая же проблема с Backbone. По-моему, это недостаток дизайна. Вот сообщение Reddit, описывающее некоторые из возможных решений: http://www.reddit.com/r/javascript/comments/11pkth/how_do_you_render_your_backbonejs_views/
Вот вопрос Джереми Ашкенаса:
| Если я хочу полностью инкапсулировать HTML внутри моего шаблона, не создавая дополнительных div, | Я должен заменить this.el. По крайней мере, насколько я знаю. Есть ли лучший способ сделать это?
Откажитесь от своего желания сделать это, и вам будет намного легче;) Большая часть точки Backbone, которая всегда предоставляет элемент вида ( "el" ) для вас, заключается в том, что ваши события действительны во все времена - независимо от того, является ли представление в DOM, если данные еще готовы, или если шаблон доступен. Это более безгражданный способ объявить события мыши и клавиатуры, меньше полагаясь на требуемый порядок вашего рендеринга. Если вы действительно хотите заменить элемент view, используйте setElement. Но это не рекомендуется или необходимо.
Ответ 6
К лучшему или худшему, в Backbone вы должны использовать el
, предоставленный представлением, и настроить его по своему вкусу с помощью свойств tagName
, className
, id
и attributes
этого вид.
Очевидная проблема с этим подходом заключается в том, что вы смешиваете и сопоставляете JS и HTML, как будто завтра нет. На мой взгляд, лучше держать вещи красиво разделенными; характеристики el
должны быть указаны вместе с шаблоном.
В 2014 году я написал компонент drop-in, целью которого является решение проблемы: Backbone.Declarative.Views, Это, вероятно, самый недооцененный из всех моих материалов с открытым исходным кодом, но он отлично работает.
Как?
Включите Backbone.Declarative.Views в свой проект. Затем поместите эти el
-defining свойства в атрибуты данных вашего шаблона.
<script id="my-template"
type="text/x-template"
data-tag-name="p"
data-id="myContainer"
data-class-name="someClass orOther">
<!-- template content here -->
</script>
Теперь, если ваше представление имеет свойство template: "#my-template"
, его el
устанавливается как
<p id="myContainer" class="someClass orOther"></p>
И это так. Для получения полной информации ознакомьтесь с документы.
Почему атрибуты данных?
Использование атрибутов данных решает основную проблему хранения связанного с HTML материала в ваших HTML файлах и шаблонах и из вашего Javascript. В то же время этот подход полностью совместимы с тем, как обычно делаются вещи в макете.
Т.е. все существующие шаблоны Backbone продолжают работать так, как они должны, точно так же, как все те tagName
определения, разбросанные по всему Javascript по-прежнему применяются как обычно. Конфликты с другими расширениями и плагинами Backbone исключаются, и нет необходимости изменять устаревший код. Это делает Backbone.Declarative.Views безопасным для включения в практически любой проект.