如何在Backbone中避免使用空div进行模板包装?

Mir*_*ron 15 javascript jquery backbone.js

当我创建视图主干时,如果未设置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);
Run Code Online (Sandbox Code Playgroud)

jcv*_*dan 15

我认为还没有提供这个问题的真正答案,只需div从模板中删除并添加className属性即可JobView!这将导致您需要的标记:

模板:

<script id="contactTemplate" type="text/html">
     <h1><%= title %>/<%= type %></h1>
     <div><%= description %></div>
</script>
Run Code Online (Sandbox Code Playgroud)

风景:

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;
            }
    });
Run Code Online (Sandbox Code Playgroud)

当你打电话时,render你将得到所需的标记:

<div class="job">
  <h1><%= title %>/<%= type %></h1>
  <div><%= description %></div>
</div>
Run Code Online (Sandbox Code Playgroud)

  • 我讨厌Backbone这样做.为什么在模板html和视图定义中都有模板代码? (2认同)

Vic*_*Vic 8

我认为最好的解决方案是:

render: function(){
    var html = this.template(this.model.toJSON()));
    var newElement = $(html)
    this.$el.replaceWith(newElement);
    this.setElement(newElement);
    return this;
}
Run Code Online (Sandbox Code Playgroud)


小智 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
     },
})
Run Code Online (Sandbox Code Playgroud)

然后在你的模板中删除该元素,这个元素将很好地创建而不包装你的模板,而不必更改你的渲染方法.


Tal*_*ris 5

您可以将视图渲染到您喜欢的任何容器中,既可以自己指定$ el属性,也可以setElement()在调用render之前使用该方法:

var jobView = new JobView({
  model:jobModel
});          

jobView.setElement($('#your_selector_here'));

console.log(jobView.el);
Run Code Online (Sandbox Code Playgroud)

如果您查看文档,View.el您将看到您也el可以在编写视图时指定属性,或者在构造函数中传递参数.


the*_*rin 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。但不推荐,也没有必要。