情况如下:第一次打开页面时,它已经通过服务器(php)准备好DOM。
如果用户打开了 javascript,那么我想将我的页面转换为网络应用程序(或任何你称之为的)。一旦 Javascript 被初始化,Backbone 就会从服务器获取集合。问题是,其中一些获取的项目已经在页面上。
现在我如何标记那些已经在 DOM 中的项目?我怎样才能将它们与 Backbone 视图联系起来?
情况如下:第一次打开页面时,它已经通过服务器(php)准备好DOM。
如果用户打开了 javascript,那么我想将我的页面转换为网络应用程序(或任何你称之为的)。一旦 Javascript 被初始化,Backbone 就会从服务器获取集合。问题是,其中一些获取的项目已经在页面上。
现在我如何标记那些已经在 DOM 中的项目?我怎样才能将它们与 Backbone 视图联系起来?
将 Backbone.View 连接到现有的 DOM 元素很简单:
//get a referent to the view element
var $el = $("#foo");
//initialize new view
var view = new FooView({el:$el});
视图现在处理#foo
元素的事件,以及所有其他视图的优点。你不应该打电话view.render
。如果这样做,它会将视图重新渲染到元素。这意味着您不能在render
方法中定义任何必要的代码。
至于如何找出 DOM 中已经存在哪些元素,以及如何为每个视图找到相应的元素 - 在不知道您的数据和 html 的具体外观的情况下,这有点复杂。作为一般建议,请考虑使用data-*
属性来匹配元素。
假设你有一个 DOM 树:
<ul id="list">
<li data-id="1">...</li>
<li data-id="2">...</li>
<li data-id="5">...</li>
</ul>
您可以像这样将模型绑定/渲染到容器:
var view;
//container element
var $list = $("ul#list");
//find item node by "data-id" attribute
var $item = $list.find("li[data-id='" + model.id+ "']");
if($item.length) {
//element was in the DOM, so bind to it
view = new View( {el:$item, model:model} );
} else {
//not in DOM, so create it
view = new View( {model:model} ).render();
$list.append(view.el);
}
好的,我设法这样做:
var Collection = Backbone.Collection.extend({...});
var ItemView = Backbone.View.extend({...});
var ItemsView = Backbone.View.extend({
initialize: function () {
var that = this,
coll = new Collection;
coll.fetch({ success: function () {
that.collection = coll;
that.render();
}});
},
render: function () {
this.collection.each(this.addOne, this);
},
addOne: function (model) {
var selector = '#i'+model.get("id");
if( $(selector).length ) {
//If we are here, then element is already in the DOM
var itemView = new ItemView({ 'model': model, 'el': selector, 'existsInDom': true });
} else {
var itemView = new ItemView({ 'model':model });
}
}
});