当我创建视图主干时,如果未设置el,则创建空div容器。模板(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);
答案 0 :(得分:15)
我认为尚未提供此问题的真实答案,只需从模板中删除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>
答案 1 :(得分:8)
我认为最好的解决方案是:
render: function(){
var html = this.template(this.model.toJSON()));
var newElement = $(html)
this.$el.replaceWith(newElement);
this.setElement(newElement);
return this;
}
答案 2 :(得分:6)
抱歉,对于迟到的回复,这可能已经解决了。我发现尽可能轻松地尝试制作模板和视图。我使用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
},
})
然后在你的模板中删除该元素,这个元素将很好地创建而不包装你的模板,而不必更改你的渲染方法。
答案 3 :(得分:5)
您可以将视图渲染到您喜欢的任何容器中,既可以自己指定$ el属性,也可以在调用render之前使用setElement()
方法:
var jobView = new JobView({
model:jobModel
});
jobView.setElement($('#your_selector_here'));
console.log(jobView.el);
如果查看View.el
的文档,您会发现在编写视图时也可以指定el
属性,或者在构造函数中传递参数。
答案 4 :(得分:2)
我遇到了与Backbone相同的问题。在我看来,这是一个设计缺陷。这是一篇Reddit帖子,描述了一些可能的解决方案:http://www.reddit.com/r/javascript/comments/11pkth/how_do_you_render_your_backbonejs_views/
Jeremy Ashkenas对这个问题的看法是:
|如果我想在我的模板中完全封装HTML,而不创建任何额外的div,|我必须更换this.el.至少据我所知。有没有更好的方法呢?
放弃你这样做的愿望,你会有更轻松的时间;) Backbone始终为您提供视图元素(“el”)的重要一点是,您的事件始终有效 - 无论视图是否在DOM中,数据是否已准备就绪,或者如果模板可用。声明鼠标和键盘事件是一种更无状态的方式,更少依赖于渲染所需的顺序。 如果您确实想要替换视图的元素,请使用setElement。但不建议或必要。
答案 5 :(得分:0)
无论好坏,在Backbone中,您应该使用视图提供的el
,并根据您的喜好使用tagName
,className
,{{1}进行调整该视图的{和} id
属性。
这种方法的一个明显问题是你混合搭配JS和HTML,就像没有明天一样。在我看来,最好把事情分开; attributes
的特征应与模板一起指定。
2014年,我编写了一个旨在解决问题的插件:Backbone.Declarative.Views。它可能是我所有开源软件中最被低估的东西,但它的工作做得很好。
如何吗
Include Backbone.Declarative.Views进入您的项目。然后,将这些el
- 定义属性放入模板的数据属性中。
el
现在,如果您的视图具有<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
就是这样,真的。有关完整的详细信息,请查看the docs。
为何选择数据属性?
使用数据属性解决了在HTML文件和模板中保留HTML相关内容以及Javascript之外的基本问题。同时,这种方法fully compatible与通常在Backbone中完成的方式相同。
即,所有现有的Backbone模板都可以继续正常工作,就像所有<p id="myContainer" class="someClass orOther"></p>
个定义分散在整个Javascript still get applied as usual中一样。避免了与其他Backbone扩展和插件的冲突,并且无需更改遗留代码。这使得Backbone.Declarative.Views可以安全地包含在几乎任何项目中。