【问题标题】:Render a view for a model on first load, not on every change在第一次加载时为模型渲染视图,而不是在每次更改时
【发布时间】:2012-08-20 13:00:47
【问题描述】:

我想在第一次获取模型时渲染模型的视图,但不是每次更改时。

我的设置如下:

var m = new $.model.Customer({id: customer});
var v = new $.view.GeneralEditView({el: $("#general"), model: m});
m.fetch();

然后在视图初始化中我将更改事件绑定到渲染方法以在模型加载时进行渲染:

this.model.bind('change', this.render);

问题是视图会在每次更改时呈现。我只想在获取后渲染。不幸的是,除了更改之外,我不知道在获取模型后触发的任何事件。

对于我可以绑定到的集合,是否有类似“重置”的东西?

编辑:

也许更简洁地说,对于 Backbone 模型,有没有办法区分模型是从服务器加载还是在本地更改?

【问题讨论】:

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


    【解决方案1】:

    有很多不同的方法可以解决这个问题(这些都假定var view = this; 在您的视图代码中的某处):

    • 使用一次性成功回调调用.fetch():

      m.fetch({
          success: function() {
              view.render();
          }
      });
      
    • 绑定到change,但在处理程序中取消绑定:

      function handle() {
          view.render();
          view.model.off('change', handle);
      }
      this.model.bind('change', handle);
      
    • 使用_.once 限制处理程序调用:

      this.model.bind('change', _.once(function() {
          view.render();
      }));
      
    • 为您的模型使用 .ready() 模式 - example here。在多个视图需要知道模型何时加载的情况下,以及何时您需要能够编写相同的代码而不用担心您的模型是否已加载时,我喜欢这个选项。这样做的缺点是每次都需要你添加一个像.isFullyLoaded()这样的模型方法来测试;好处是使用测试函数而不是设置标志,允许模型作为集合的一部分批量加载,而无需更改代码。

    【讨论】:

    • 我认为这是唯一可靠的方法。使用同步的新事件的方法不能保证模型在同步完成后正确填充,因此会导致问题。选择了“关闭”的方法。谢谢
    【解决方案2】:

    模型

    您可以使change 事件特定于某个键的更改,例如uniqueId(如果有的话):

    this.model.bind('change:id', this.render, this);
    

    默认情况下,fetch 不会直接触发任何事件,而是在使用 set 加载新数据后间接触发 change 事件

    如果这不是一个选项,您可以随时在 fetch 函数中触发事件:

    initialize: function () {
        this.model.bind("fetch", this.update, this);
    }
    
    fetch: function () {
        // do stuff
        this.model.trigger("fetch", this);
    }
    
    update: function () {
        // your refresh stuff here
    }
    

    【讨论】:

    • 感谢奥斯汀。问题是关于模型而不是集合。我知道集合的重置,并为模型寻找类似的东西,或者除了改变之外的其他方式。
    • 那么第二部分详细介绍如何使用模型执行此操作应该适合您的需求......
    • 但我真的很想知道提取何时完成,而不是开始,因为我想在提取完成时呈现视图。
    • 然后将this.model.trigger 放入AJAX 调用的回调中
    【解决方案3】:

    我可能有来自https://github.com/documentcloud/backbone/pull/1468#issuecomment-6766096 的通用解决方案。我重写了 Backbone 上的同步方法如下:

    Backbone.Model.prototype.sync = function(method, model, options) {
    
        var succ = options.success;
        var customSuccess = function(resp, status, xhr) {
             //call original
            succ(resp, status, xhr);
            model.trigger('synced', model, options);
        }
        options.success = customSuccess;
        Backbone.sync(method, model, options);
     }
    

    为了保存原始成功方法,因为我不想弄乱它,除非我需要,传递自定义成功方法。当调用自定义成功方法时,会按照@Austin 的建议触发自定义事件,然后调用原始成功方法。

    【讨论】:

    • 很想知道是否有人可以预见这种方法的问题。我只是有点不确定“这个”的范围会如何受到所有这些的影响......
    猜你喜欢
    • 1970-01-01
    • 2015-06-23
    • 1970-01-01
    • 1970-01-01
    • 2023-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多