【问题标题】:Backbonejs view binding conceptual feedbackBackbonejs 视图绑定概念反馈
【发布时间】:2016-07-04 13:45:04
【问题描述】:

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

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

【问题讨论】:

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


    【解决方案1】:

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

    在您的示例中,视图绑定到 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();一起去

    【讨论】:

      【解决方案2】:

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

      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 函数,甚至通过重置您的集合来完成。或者,如果您通过主干导航到同一条路线,整个过程将重复,因此您的集合将被再次调用,并且页面将从头开始呈现。因此,这取决于您对何时/为什么选择一个而不是另一个的偏好。希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 2021-06-15
        • 1970-01-01
        • 1970-01-01
        • 2013-01-15
        • 2012-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多