Backbonejs 视图绑定概念反馈

Backbonejs view binding conceptual feedback

我 运行 进入这篇文章 (http://coenraets.org/blog/2012/01/backbone-js-lessons-learned-and-improved-sample-app/) 并且想知道在实例化它们之后在路由器中绑定和呈现视图的想法是否是最佳实践。我一直在绑定我的视图并将它们呈现在我的视图定义中。

目前我是这样设置和调用我的视图的:

员工视图:

  EmployeeView = Backbone.View.extend({
  el: '#content',
  template:template,

  initialize: function () {

    this.collection.fetch({
      reset: true
    });

    this.collection.on('reset',this.render, this);
  },
  render: function(){
    this.el.innerHTML = Mustache.to_html(this.template, { employee_list: this.collection.toJSON()});
    console.log('render called');     
  }

我的路由器:

 employeeList: function () {
    var c = new EmployeeCollection
     new EmployeeView( {
       collection: c
     });
  }

它工作正常。但根据文章,更好的做法是执行以下操作:

  EmployeeView = Backbone.View.extend({

  template:template,

  initialize: function () {

    this.collection.fetch({
      reset: true
    });

    this.collection.on('reset',this.render, this);
  },
  render: function(){
    this.el.innerHTML = Mustache.to_html(this.template, { employee_list: this.collection.toJSON()});
    console.log('render called');  
    return this;
  }

路由器

  employeeList: function () {
    var c = new EmployeeCollection
    $('#content').html(new EmployeeView( {collection: c}).render().el);
  },

我喜欢文章中的解决方案,因为它如文章所述将视图与其他 DOM 事件分离,并允许我将所有调整和自定义集中在一个地方,路由器。但是因为我传入了一个 collection/model 并且需要在我的初始化中获取数据,所以我的页面呈现了两次。我的问题是:

  1. 这真的是最佳做法吗?
  2. 如果我想使用建议的方法,如何避免调用两次渲染?
  3. 如果遇到一些前端用户交互然后需要刷新视图的情况怎么办 collection/model?在我看来我必须这样做还是在路由器中也可能发生?

你几乎答对了。你只是渲染它两次,我认为这不是正确的方法,因为没有意义。

EmployeeView = Backbone.View.extend({
  template:template,

  initialize: function(){
    console.log("Will print second");
    this.collection.fetch({ reset: true });
    this.collection.on('reset', this.appendEmployees, this);
  },
  render: function(){
    //this.el.innerHTML = Mustache.to_html(this.template, { employee_list: this.collection.toJSON()});
    console.log('Will print 3rd. render called');  
    return this;
  }

  appendEmployees: function(){
    console.log("Will print 4th. Appending employees");
    $(this.el).html(Mustache.to_html(this.template, {employee_list: this.collection.toJSON() });
  }

})

路由器

employeeList: function () {
  var c = new EmployeeCollection()
  var view = new EmployeeView({ collection: c });
  console.log("Will print 1st");
  $('#content').html(view.render().el);
}

首先,当您执行 view.render().el 时,它会将视图的元素(届时将为空)附加到 #content

其次,当 collection 重置时,您正在执行 appendEmployees 函数。到这时,您的元素将已经放置在 DOM.

如果您需要刷新,可以在视图内完成,方法是调用 appendEmployees 函数,甚至重置您的 collection。或者,如果您通过 backbone 导航到相同的路线,整个过程将重复,因此您的 collection 将被再次调用,并且页面将从头开始呈现。因此,这取决于您对 when/why 的偏好,您会选择一个而不是另一个。希望这有帮助。

你这里的观点和文章中的观点完全不同。

在您的示例中,视图绑定到 DOM (#content),
中的元素 这不是一个好的做法,特别是对于初学者来说,并且会导致我们每天在这里看到很多错误。

例如,如果您创建了视图的 2 个实例,那么事件将开始触发多次,随之而来的一切都会崩溃。


文章中的视图为每个实例在内存中创建一个新的 <div> 元素,这是一个很好的做法。

现在,要在 DOM 中添加它,新手通常会在 内部 视图的渲染中执行类似以下操作:

$('#content').html(this.$el);

这会在视图内部创建一个全局选择器,并使其了解外部世界,这不是一个好的做法。

这篇文章可能(我没读过)解决了这个问题,并提出了从路由器向 DOM 添加视图元素的替代方法,我认为这是一个很好的做法。


为了避免在文章中的代码中渲染两次,您可以这样做:

$('#content').html(new EmployeeView( {collection: c}).el);

el 作为实时引用,它会在获取成功时更新。 .render().el 是所有现有博客和教程传播的另一个常见误解。


旁注:由于我们正在讨论最佳实践,因此省略 var c = new EmployeeCollection 中的分号和括号也不是一个好的做法。选择 var c = new EmployeeCollection();