仅使用模板构建 backbone 视图
Use only template to build backbone view
var ItemView = Backbone.View.extend({
tagName:"li",
className:"l-item",
template:_.template("#tpl-list-item"),
.....
});
var ListView = Backbone.View.extend({
render:(){
this.collection.each(function(model){
this.$el.append(new ItemView({model:model}).render().$el);
});
}
});
<script id="tpl-list-item" type="text/template">
<div>
// other markup
<div>
</script>
如图所示,一旦我想更新 itemview 的表示,我将不得不同时检查 js 和模板文件。
而且我更喜欢从模板构建视图,只是为了避免在代码中设置表示形式,例如:
<script id="tpl-list-item" type="text/template">
<li class="....">
<div>
// other markup
<div>
</li>
</script>
这可能吗?
如果我对你的问题的理解正确,你想直接从模板构建 html 吗?
这可能不是个好主意。视图应处理模板的呈现。从技术上讲,您可以执行以下操作:
var ListView = Backbone.View.extend({
render: function(){
var itemTemplate = "#tpl-list-item";
this.collection.each(function(model){
this.$el.append(_.template(itemTemplate,{item:model}));
});
}
});
然而,这样做的问题是,现在如果 itemTemplate
需要修改,它没有视图来处理该逻辑。为了使事情尽可能模块化,你最好通过自己的视图呈现模板,这样你就可以 update/destroy 模板,但是你喜欢作为视图。视图的目的很简单:
to organize your interface into logical views, backed by models, each of which can be updated independently when the model changes, without having to redraw the page. -Backbone.js
您可以使用 setElement
替换视图的 el
:
setElement view.setElement(element)
If you'd like to apply a Backbone view to a different DOM element, use setElement, which will also create the cached $el
reference and move the view's delegated events from the old element to the new one.
实际上,它看起来像这样:
var ItemView = Backbone.View.extend({
template: _.template("#tpl-list-item"),
render: function() {
this.setElement(this.template(this.model.toJSON()));
return this;
},
//...
});
和ListView
不需要改变。
演示:https://jsfiddle.net/ambiguous/fs9h6o09/
这种方法最终将创建和丢弃一堆 <div>
节点,因为如果您不告诉它,视图将创建空的 <div>
作为 el
通过 id
、className
、... 属性做其他事情。这些额外的 <div>
可能不会产生任何明显的差异,但您可以使用一些 el: '#no-such-id'
技巧来避免它们。
Backbone 没有设置那么多的策略,但它确实想要将 el
与其内部的内容分开。你不必遵循这个,但你按照自己的方式去做是违背规律的。
您可以避免使用 setTemplate()
,即免费创建和丢弃节点,并且仍然将您的视图 HTML 全部放在模板中的一个位置。
Backbone.Decarative.Views provides you with a clean way to do this. For more, check out my answer here.
var ItemView = Backbone.View.extend({
tagName:"li",
className:"l-item",
template:_.template("#tpl-list-item"),
.....
});
var ListView = Backbone.View.extend({
render:(){
this.collection.each(function(model){
this.$el.append(new ItemView({model:model}).render().$el);
});
}
});
<script id="tpl-list-item" type="text/template">
<div>
// other markup
<div>
</script>
如图所示,一旦我想更新 itemview 的表示,我将不得不同时检查 js 和模板文件。
而且我更喜欢从模板构建视图,只是为了避免在代码中设置表示形式,例如:
<script id="tpl-list-item" type="text/template">
<li class="....">
<div>
// other markup
<div>
</li>
</script>
这可能吗?
如果我对你的问题的理解正确,你想直接从模板构建 html 吗?
这可能不是个好主意。视图应处理模板的呈现。从技术上讲,您可以执行以下操作:
var ListView = Backbone.View.extend({
render: function(){
var itemTemplate = "#tpl-list-item";
this.collection.each(function(model){
this.$el.append(_.template(itemTemplate,{item:model}));
});
}
});
然而,这样做的问题是,现在如果 itemTemplate
需要修改,它没有视图来处理该逻辑。为了使事情尽可能模块化,你最好通过自己的视图呈现模板,这样你就可以 update/destroy 模板,但是你喜欢作为视图。视图的目的很简单:
to organize your interface into logical views, backed by models, each of which can be updated independently when the model changes, without having to redraw the page. -Backbone.js
您可以使用 setElement
替换视图的 el
:
setElement
view.setElement(element)
If you'd like to apply a Backbone view to a different DOM element, use setElement, which will also create the cached
$el
reference and move the view's delegated events from the old element to the new one.
实际上,它看起来像这样:
var ItemView = Backbone.View.extend({
template: _.template("#tpl-list-item"),
render: function() {
this.setElement(this.template(this.model.toJSON()));
return this;
},
//...
});
和ListView
不需要改变。
演示:https://jsfiddle.net/ambiguous/fs9h6o09/
这种方法最终将创建和丢弃一堆 <div>
节点,因为如果您不告诉它,视图将创建空的 <div>
作为 el
通过 id
、className
、... 属性做其他事情。这些额外的 <div>
可能不会产生任何明显的差异,但您可以使用一些 el: '#no-such-id'
技巧来避免它们。
Backbone 没有设置那么多的策略,但它确实想要将 el
与其内部的内容分开。你不必遵循这个,但你按照自己的方式去做是违背规律的。
您可以避免使用 setTemplate()
,即免费创建和丢弃节点,并且仍然将您的视图 HTML 全部放在模板中的一个位置。
Backbone.Decarative.Views provides you with a clean way to do this. For more, check out my answer here.