在创建新的Backbone视图时如何知道元素是否已经存在于DOM中

时间:2013-01-23 14:39:16

标签: backbone.js backbone-views

这是情况: 当页面第一次打开时,它已经通过服务器(php)准备了DOM。

如果用户打开了javascript,那么我想将我的页面转换为网络应用程序(或任何你称之为的)。 初始化Javascript后,Backbone从服务器获取集合。 问题是,这些获取的项目中的一些已经在页面上。

现在我如何标记DOM中已有的项目? 我怎样才能将它们与Backbone视图联系起来?

2 个答案:

答案 0 :(得分:6)

将Backbone.View连接到现有DOM元素很简单:

//get a referent to the view element
var $el = $("#foo");

//initialize new view
var view = new FooView({el:$el});

视图现在处理#foo元素的事件以及所有其他View优点。你不应该致电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);
}

答案 1 :(得分:1)

好的,我设法这样做了:

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 });
    }
  }
});