如何将Backbone.View.el绑定到没有包装器的模板?

时间:2014-02-24 08:57:47

标签: javascript backbone.js

这是我正在使用的模板

<script type="text/template" id="template-message">
  <p class="message"><%= message %></p>
</script>

这是我的Backbone.View

var MessageView = Backbone.View.extend({

  template: _.template(Backbone.$("#template-message").html()),

  render: function() {
    this.$el.html(this.template(this.model.attributes));
    return this;
  },
});

我是如何使用的

var msg  = new Message({message: "hello"}),
    view = new MessageView({model: msg});

$("body").append(view.render().el);

输出

<body>
  <div>
    <p class="message">
      hello
    </p>
  </div>
</body>

理解为什么正在发生(视图的默认tagName是div),但我不希望包装器div在那里。我想将此视为输出

<body>
  <p class="message">
    hello
  </p>
</body>

我知道我可以在我的视野中看到这个

var MessageView = Backbone.View.exntend({
  tagName: "p",
  className: "message",
  // ...
});

最终用户将定义模板,因此我不希望在Backbone.View源代码中指定这些内容。

如何获得所需的输出并仍将视图绑定到html?

2 个答案:

答案 0 :(得分:1)

感谢@ Gohn67的评论,我能够让这个工作

var MessageView = Backbone.View.extend({

  template: _.template(Backbone.$("#template-message").html()),

  initialize: function() {
    this.setElement(this.template(this.model.attributes));
  }

});

如果我们查看Backbone Source Code,我们可以看到setElement执行我们想要的所有操作

// backbone source code
setElement: function(element, delegate) {
  if (this.$el) this.undelegateEvents();
  this.$el = element instanceof Backbone.$ ? element : Backbone.$(element);
  this.el = this.$el[0];
  if (delegate !== false) this.delegateEvents();
  return this;
},

它甚至处理事件委托。酷!


我最近不得不在jQuery 1.3.2上实现它。 Gross ,我知道,但这是一个简单的修复。

唯一改变的部分是setElement

  initialize: function() {
    this.setElement(
      $( this.template(this.model.attributes) )
    );
  }

template结果必须包含在$()中才能生效。我知道,考虑到Backbone已经尝试自动执行此操作,这没有多大意义。这是我唯一能做到的,它可以使用jQuery 1.3.2。

答案 1 :(得分:0)

您还可以使用Backbone.Declarative.Views(我已经写过)并将el属性(如tagNameclassName等)定义为模板中的数据属性。请参阅this answer on SO