Backbone View渲染:fetch-first与render-first,两种方法都有错误?

时间:2013-05-14 22:36:35

标签: javascript backbone.js underscore.js marionette

这更像是一个概念/建筑问题而不是任何东西;构建和实例化Backbone Views的典型/流行方法似乎只是从服务器(在fetchsuccess()回调中成功done()呈现视图AFTER必要的模型/集合数据)。

这一切都很好,但如果在fetch之前/期间需要在View模板中有某种加载指示符或UI元素,该怎么办?通过在调用完成之前不呈现视图,您实际上无法向用户显示此类通知。

相反,如果您在制作fetch之前渲染视图,您现在可以显示此类UI元素,但现在您可能会冒显示空白模板的风险,因为您的模型/收藏数据还没有检索到,这看起来很奇怪。

如果您同时需要这两件事:在fetch之前/期间进行用户界面通知,而不是在fetch之前呈现大部分为空的模板,该怎么办?什么可能是实现这一目标的好方法?

3 个答案:

答案 0 :(得分:4)

我使用单独的加载视图来处理加载gif,该加载gif侦听从模型/集合获取结果中触发的相关事件。负责渲染的视图在不关心加载gif的情况下这样做。加载gif基本上掩盖了当移除加载gif时“显露”的结果:

var MyView = Backbone.View.extend({

    initialize: function () {

        this.listenTo(this.collection, 'reset', this.render);
    },

    render: function () {
        // do whatever you need to here
    }
});

var LoadingView = Backbone.View.extend({

    el: '#loading',

    initialize: function () {

        this.listenTo(this.collection, 'fetchStarted', this.showLoader);
        this.listenTo(this.collection, 'fetchFinished', this.hideLoader);
    },

    showLoader: function () {

        var self = this;

        if (this.waitHandle) {
            clearTimeout(this.waitHandle);
            delete this.waitHandle;
        }
        this.waitHandle = setTimeout(function () {
             self.$el.removeClass('hide');
        }, 300);
     },

     hideLoader: function () {

         clearTimeout(this.waitHandle);
         delete waitHandle;
         this.$el.addClass('hide');
    }
});

var MyCollection = Backbone.Collection.extend({

     getResults: function () {

         var self = this;

         this.fetch({
             beforeSend: function () {
                 self.trigger('fetchStarted');
             },
             complete: function () {
                 self.trigger('fetchFinished');
             }
          });
      }
});

我在加载视图中使用超时来延迟显示加载gif,以防它们不必要。

答案 1 :(得分:2)

我通常有一个应用程序级视图,它会在知道应用程序的主要集合之一被提取时显示加载程序。面对我通常在过滤之前做一个ajax总是弹出加载器,并在完成应用程序范围时隐藏。它会阻止整个UI,但这很好,除非我正在做一个更复杂的仪表板类型的应用程序,其中存在明显的模块化问题。

答案 2 :(得分:1)

我写了一篇博文,其中包含您可能感兴趣的解决方案(http://davidsulc.com/blog/2013/04/01/using-jquery-promises-to-render-backbone-views-after-fetching-data/)。基本上,解决问题的方法之一是:

  1. 存储fetch调用的返回值(这是一个jQuery承诺)
  2. 渲染加载视图(使用MyApp.myRegion.show(loadingView);
  3. 如果需要,您可以在此时实例化您的视图(需要数据)
  4. 当履行承诺(即完成提取)时,在区域内显示您的数据相关视图(如上所述)