Backbonejs查看绑定概念反馈

时间:2016-07-04 13:45:05

标签: backbone.js backbone-views backbone-events backbone-routing backbone-collections

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

目前,这就是我设置和调用我的观点的方式:

EmployeeView:

  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事件分离,如文章所述,并允许我将所有调整和自定义集中在一个地方,即路由器。但是因为我传入了一个集合/模型,需要在初始化中获取数据,我的页面渲染两次。我的问题是:

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

2 个答案:

答案 0 :(得分:1)

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

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

其次,当集合重置时,您正在执行appendEmployees功能。到此时,您的元素将被放置在DOM中。

如果您需要刷新,可以在视图内部,通过调用appendEmployees函数,甚至重置您的集合来完成。或者,如果您通过骨干导航到相同的路线,整个过程将重复,因此您的收集将再次被调用,页面将从头开始渲染。因此,这取决于您对何时/为何选择一个而不是另一个的偏好。希望这会有所帮助。

答案 1 :(得分:1)

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

在您的示例中,视图绑定到DOM中的元素(#content),
这不是一个好习惯,特别是对于初学者而言,每天都会出现很多错误。

例如,如果您创建了2个视图实例,那么事件将开始触发多次,并且所有地狱都会破裂。

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

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

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

这会在视图中创建一个全局选择器,使其了解外部世界,这不是一个好习惯。

这篇文章可能(我没有读过)解决了这个问题,并提出了将路由器中的视图元素添加到路由器的替代方案,这在我看来是一个很好的做法。

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

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

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

旁注:由于我们正在讨论最佳实践,省略var c = new EmployeeCollection中的分号和括号也不是一个好习惯。使用var c = new EmployeeCollection();