2013-03-12 82 views
1

我在我的fetch调用(在我的集合中)添加了对setInterval的调用,并且它创建了一个意想不到的副作用。这里是正在调用集合的观点:Backbone.js和setInterval:如何检查DOM中是否有东西

define([ 
    'jquery', 
    'underscore', 
    'backbone', 
    'models/tableModel', 
    'collections/tablesCollection', 
    'views/tableView' 
], 
function($, _, Backbone, tableModel, tablesCollection, tableView) { 
    var tablesView = Backbone.View.extend({ 
     tagName: 'div', 
     initialize: function(options) { 
      this.collection.on('reset', this.render, this); 
      this.template = this.options.template; 
      this.url = this.options.url; 
     }, 
     render: function() { 
      this.collection.each(this.addOne, this); 
      return this; 
     }, 
     addOne: function(model) { 
      var TableView = new tableView({ model: model, template: this.template, url: this.url }); 
      $(this.$el).append(TableView.render().el); 
      return this; 
     } 
    }); 

    return tablesView; 
}); 

正如你所看到的,这一观点通过收集迭代,每个追加导致的DOM,这就是我想要的。但是每次获取集合时都会调用setInterval。这是我想要的,但我想在append之前添加一行以检查项目是否已在DOM中。我想我可以使用model.get('id'),并将其与DOM进行比较。这是最好的方法吗?如果是这样,我该怎么做?

回答

0

对于这种类型的事情基本/天真的模式是有一个渲染方法如下这个模式:

render: function() { 
    this.$el.empty() 
    this.collection.each(this.addOne, this); 
    return this; 
} 

否则你的DOM和收集将不同步,因为你已经注意到了。如果你正在做一些非常激烈的事情(这也可能是不明智的),例如每隔100ms重绘一次集合或渲染5000个模型,你可能需要更复杂的方法,但这些都是代码气味,你的方法是错误的。如果你想要实时的东西,请查看socket.io和pub/sub。如果您打算使用setInterval进行服务器轮询,只需KISS并清空视图并重新渲染所有内容。

既然你这么问,如果你确实需要避免与手动(和易碎)检查重新渲染,穿上模型视图的最外层标签的data-id="<%= model.id %>"属性,然后检查this.$('[data-id=' + model.id + ']').length,以确定它是否在DOM已经或没有。

+0

谢谢彼得。我知道必须有办法做到这一点。 – sehummel 2013-03-12 21:59:25

+0

现在我听到了,第二部分听起来有点粗略。我最喜欢你的第一种方法。再次感谢。 – sehummel 2013-03-12 22:05:25

相关问题