0

再会!

最近我进入了骨干网/需求,并开始学习一些非常酷的东西。我正在尝试了解在获取主干集合时显示加载条/微调器的最佳做法是什么。以下是我发现使用的一些策略,用于触发集合上的获取/同步事件:

方法 1:在应用程序启动之前覆盖主干的同步方法,并在该集合上触发“同步”事件

方法 2:在应用程序启动之前覆盖主干的 fetch 方法,并在该集合上触发 'fetching' 事件

方法三:当一个集合被定义时,重写 fetch() 方法并触发一个事件 'fetching',这样任何实例都可以被监听获取

方法四:有人建议使用事件聚合,这样当视图调用 fetch() 获取集合时,该视图会触发事件。

这是我的情况:

  • 假设我有一个集合 C
  • 有 2 个视图 V1 和 V2 可以访问它
  • V1 可以在 C 上调用 fetch 但 V2 不能
  • 当 C 开始 fetch 时,只有 V2 应该显示一个加载栏,并在 C 上调用 reset() 时将其关闭
  • 还可以有其他视图 V3、V4 等,在获取 C 时可能也需要加载栏

显示加载栏的最佳机制是什么,保持严格的 MVC 模式完好无损?

选项 1:视图是否应该监听集合上的“同步”事件?问题:如果调用了其他的 fetch()、save(),加载栏可能会显示

选项 2:视图是否应该监听集合上的 'fetch()' 事件并采取相应的行动?

选项 3:一个视图是否应该在对集合调用 fetch() 时通知另一个视图?

选项 4:视图应该调用窗口上的获取方法还是事件聚合器?

也欢迎其他方法和选项。您的建议和意见将是最好的资源。谢谢。

4

1 回答 1

3

在 Backbone.View 的上下文中,例如:

initialize: function() {
   this.state_loading();

   // assuming this.collection is your collection which is not fetched yet...       
   this.collection.bind('reset', this.state_loaded, this);
   this.collection.fetch();
},

state_loading: function() {
   this.el.addClass('st-loading');
},

state_loaded: function() {
   this.el.removeClass('st-loading');
}

现在.st-loadingView 元素上的类将在您需要的任何地方简单地显示一个微调器,例如

.ajax-spinner { backgrund: url('...'); display: none; }
.st-loading .ajax-spinner { display: block; }

现在想想你的选择:

方法 1:不要覆盖库。下一个在生产中处理您的代码的人会因此而诅咒您。

方法 2:最好在集合上触发自定义事件,不需要覆盖任何本机 Backbone 方法。同样,只有当您无法提出好的解决方案时,才会进行这种类型的黑客攻击。

方法 3:我猜您的想法是每次加载某些内容时您都想显示一个微调器?我会为你的用户感到难过。

方法 4:如果这发生在一个视图中,则不需要使用事件中心。最后,您可以在集合上触发自定义事件,并且父小部件可以订阅它。另一个考虑因素是您很可能需要在不同类型的元素中显示微调器,并且您需要为它们传递引用或选择器以用于不同的视图。现在如果你想要一个通用的解决方案,当然你可以给你的微调器提供相同的类应用程序,但是如果有一天你想删除它们,你会很头疼。您最好将这些内容本地化到您的视图中。

我们在一个由 Backbone 驱动的大型应用程序中遇到了类似的情况。为此,我们有一个扩展,我们将其应用于需要显示微调器的视图。它看起来有点像这样:

var state_loading: function() {
  if (arguments.length === 0 || arguments[0] === true) {
    this.el.addClass('st-loading');
  } else {
    this.el.removeClass('st-loading');
  }
}

var SomeView = Backbone.View.extend({
  initialize: function(options) {
    this.options = _.extend({}, this.options || {}, options || {});
    this.collection = this.options.collection;
    this.collection.bind('reset', this.render, this);
    this.state_loading(true);
    this.collection.fetch();
  },

  render: function() {
    this.state_loading(false);
    // your code...
  }
});

_.extend(SomeView.prototype, state_loading);
于 2012-10-23T07:00:32.713 回答