骨干,而不是"this.el"包装



我大量使用模板,并且我喜欢使用full-contended模板。我的意思是,我想在模板代码中看到所有DOM元素,包括元素,如下所示:

<script type="text/template" id="template-card">
  <div class="card box" id="card-<%= id %>">
    <h2><%= title %></h2>
    <div><%= name %></div>
  </div>
</script>

但Backbone喜欢的是有一个模板,如下所示:

<script type="text/template" id="template-card">
  <h2><%= title %></h2>
  <div><%= name %></div>
</script>

并在JS代码中定义root元素及其属性。我认为这是丑陋和令人困惑的。

那么,有什么好方法可以避免我的Backbone视图用额外的DOM元素包装我的模板吗

我一直在检查这个问题线程:https://github.com/documentcloud/backbone/issues/546我知道没有任何官方的方式来做这件事…但也许你可以向我推荐一种非官方的方式。

您可以利用view.setElement来呈现一个完整的模板,并将其用作视图元素。

setElement view.setElement(element)
如果您想将Backbone视图应用于不同的DOM元素,请使用setElement,它将还创建缓存的$el引用并移动视图的委派从旧元素到新元素的事件

你必须考虑两点:

  1. setElement调用undelegateEvents,负责视图事件,但要小心删除您可能自己设置的所有其他事件
  2. setElement不会将元素注入DOM,您必须自己处理

也就是说,你的观点可能看起来像这个

var FullTemplateView = Backbone.View.extend({
    render: function () {
        var html, $oldel = this.$el, $newel;
        html = /**however you build your html : by a template, hardcoded, ... **/;
        $newel = $(html);
        // rebind and replace the element in the view
        this.setElement($newel);
        // reinject the element in the DOM
        $oldel.replaceWith($newel);
        return this;
    }
});

还有一个可以发挥作用的例子http://jsfiddle.net/gNBLV/7/

现在您还可以将视图的tagName定义为一个函数,并创建这样的类:

var MyView = Backbone.View.extend({
   template: '#my-template',
   tagName: function() {
     // inspect the template to retrieve the tag name
   },
   render: function() {
     // render the template and append its contents to the current element
   }
});

下面是一个工作示例

Backbone.Decarative.Views为您提供了一种替代方法,而不必依赖setElement。要了解更多信息,请在此处查看我的答案。

最新更新