如何将现有的dom元素绑定到主干集合视图

时间:2013-01-19 15:45:30

标签: javascript backbone.js

我在页面上有一系列评论,可以编辑。我的想法是通过Rails呈现注释并在Backbone Collection中预加载带有所有这些注释的json。

然后我会每隔x秒轮询一次,看是否有变化。通常我通过循环遍历所有模型来渲染集合,并为每个项目创建一个视图。当模型得到更新时,视图也会更新(在这种情况下发表评论)。

但我的问题是,当视图已经在DOM中时,如何将视图绑定到模型。特别是因为视图具有动态id。渲染视图没有意义,因为它已经存在了。渲染视图时,骨干将其绑定到某个cid。

我能想到的唯一解决方案是在pageload上的dom对象中设置id。哇

<div id="comment-<%= content.id %>"></div>

。然后在视图的初始化中,重置id

class Comment extends Backbone.View
    initialize: ->
       @id = "comment-" + @model.get('id')

但是我不确定那是不是这样。事件仍然会被绑定吗?

1 个答案:

答案 0 :(得分:2)

特别适合你:)

var CommentsView = Backbone.View.extend({
  tagName : 'ul',
  comments : {},
  initialize : function () {
    this.listenTo(this.collection, 'add', this.addComment);
    this.listenTo(this.collection, 'remove', this.removeComment);
    this.listenTo(this.collection, 'change', this.updateComment);
  },
  addComment : function (model) {
    this.comments[model.id] = new CommentView({model:model});
    this.$el.append(this.comments[model.id].render().$el);
  },
  removeComment : function (model) {
    this.comments[model.id].remove();
    this.comments[model.id] = null;
  },
  updateComment : function (model) {
    this.comments[model.id] = new CommentView({model:model});
    this.$('[data-id="' + model.id + '"]').before(this.comments[model.id].render().$el).remove();
  }
});

var CommentView = Backbone.View.extend({
  tagName : 'li',
  template : _.template('<div data-id="<%= id %>"><%= name %>: <%- message %></div>'),
  render : function () {
    this.$el.html(this.template(this.model.toJSON()));
    return this;
  }
});

// comments
var initialComments = [{id:1, name:'user1', message:'great!'}, {id:2, name:'user2', message:':)'}];
var actualComments = [{id:1, name:'user1', message:'great! [edited]'}];

var comments = new Backbone.Collection();
var commentsView = new CommentsView({collection:comments});

// show comments
commentsView.render().$el.appendTo('body');

// simulate fetch
comments.add(initialComments);

// simulate update
_.delay(function() {
  comments.update(actualComments);
},
2000);

jsfiddle