骨干JS视图非常“有用”,因为它们总是为您创建一个DOM节点,带有一个可配置的标记、id和类。这很好,也很方便,但我发现它造成了一种不幸的情况:视图创建的DOM节点是一个隐藏的模板。
在我们当前的项目中,这一点对我来说是显而易见的,我们在前端和后端之间共享胡子模板。当您想要一个如下所示的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">但是现在模板被绑定到主干视图中的秘密根节点模板,这需要在服务器端复制。干封装就这么多了!
除了在呈现时将setElement()与呈现的模板一起使用之外,我没有看到一种立即解决这个问题的显而易见的方法,但这带来了其他问题,比如必须在每个render()之后替换DOM中新呈现的子树。
你是如何处理这个问题的?
发布于 2013-01-23 01:09:21
这是个有趣的问题。我从来没有解决过这个特殊的问题,但我尝试了几个选择,我想我找到了一个我喜欢的。
首先,下面是代码:
//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);
}
});本质上,您定义了一个基本视图,它期望每个派生视图都具有一个template属性,或者在选项哈希中将一个template作为参数。模板可以是字符串、DOM节点或jQuery/Zepto -wrapped DOM节点。该视图假定模板的根节点为其el,并将template属性重新定义为根节点的contents。
您可以将其用作正常视图:
var View = RootlessView.extend({
template: templateHtml,
render: function() {
this.$el.html(Mustache.render(this.template, this.model));
return this;
}
}); el属性在启动时是可用的,并且在重新呈现时不会分离和重新附加。普通Backbone.View行为的唯一例外是,如果定义了id、cssClass或tagName属性或参数,它们将被忽略,因为模板提供根元素。
这不是广泛测试,但似乎通过了大多数简单的测试用例。我能想到的唯一缺点是,template html字符串存储在每个视图实例(而不是原型)上,浪费了宝贵的内存字节,但这一点也不难解决。
这是一个在JSFiddle上的工作演示。
发布于 2013-01-23 00:10:22
解决方案是将根节点本身(在本例中是节标记)包含在共享基模板(没有子模板)中,然后在实例化时初始化视图的"el“属性:
var existingElement = $('section.note')[0];
new View({el: existingElement}) 然后,您可以继续将表单模板按常规方式附加到el属性。
https://stackoverflow.com/questions/14470014
复制相似问题