Backbone JS View 非常“有用”,因为它们总是为您创建一个 DOM 节点,带有可配置的标签、id 和类。这是非常好的和包容的,但我发现它造成了一个不幸的情况:View 创建的 DOM 节点是一个隐藏的模板。
在我们当前的项目中,这对我来说变得很明显,我们在前端和后端之间共享 Mustache 模板。使用 Backbone,当你想要一个看起来像这样的 DOM 时:
<section class="note">
<textarea>
...
</textarea>
<input type="button" class="save-button" value="Save">
<input type="button" class="cancel-button" value="Cancel">
</section>
您最终会创建如下所示的模板:
<textarea>
{{& content}}
</textarea>
<input type="button" class="save-button" value="Save">
<input type="button" class="cancel-button" value="Cancel">
但现在您的模板与主干 View 上的 secret 根节点模板相关联,需要在服务器端进行复制。干封装到此为止!
除了在渲染时对渲染模板使用 setElement()
之外,我没有看到一个立即明显的方法来解决这个问题,但这会带来其他问题,比如必须替换在每次 render()
之后,DOM 中新呈现的子树。
你是如何解决这个问题的?
最佳答案
这是一个有趣的问题。我以前从来没有解决过这个特殊问题,但我尝试了几个选项,我想我找到了一个我喜欢的。
首先,这是代码:
//A base view which assumes the root element of its
//template (string, DOM node or $) as its el.
var RootlessView = Backbone.View.extend({
//override the view constructor
constructor: function(options) {
//template can be provided by constructor argument or
//as a subclass prototype property
var template = options.template || this.template;
//create a detached DOM node out of the template HTML
var $el = Backbone.$(template).clone()
//set the view's template to the inner html of the element
this.template = $el.html();
//set the element to the template root node and empty it
this.el = $el.empty()[0];
//call the superclass constructor
Backbone.View.prototype.constructor.apply(this, arguments);
}
});
本质上,您定义了一个基础 View ,它期望每个派生 View 都有一个 template
属性,或者将一个 template
作为选项散列中的参数。模板可以是字符串、DOM 节点或 jQuery/Zepto 包装的 DOM 节点。 View 假定模板的根节点为其 el
,并将 template
属性重新定义为根节点的 contents。
您可以将其用作普通 View :
var View = RootlessView.extend({
template: templateHtml,
render: function() {
this.$el.html(Mustache.render(this.template, this.model));
return this;
}
});
el
属性从一开始就可用,它不会在重新渲染时分离和重新附加。正常 Backbone.View
行为的唯一异常(exception)是,如果您定义了 id
、cssClass
或 tagName
属性或参数,它们将被忽略,因为模板提供了根元素。
这没有经过广泛的测试,但似乎通过了大多数简单的测试用例。我能想到的唯一缺点是 template
html 字符串存储在每个 View 实例(而不是原型(prototype))上,浪费了宝贵的内存字节,但这也不难解决.
这是一个working demo on JSFiddle .
关于Backbone.js:如何最有效地将我共享的 Mustache 模板应用到 View 的 el?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14470014/