【问题标题】:backbone.js - how and when to show a spinnerBackbone.js - 如何以及何时显示微调器
【发布时间】:2011-04-29 12:52:50
【问题描述】:

主干中是否有任何类型的钩子,我可以轻松地说“每当任何集合正在获取数据时,显示微调器,完成后将其隐藏”?

我感觉它会比这更复杂,并且需要覆盖特定的函数。我应该什么时候展示微调器?在fetch()refresh() 或其他什么地方?

【问题讨论】:

    标签: javascript jquery backbone.js underscore.js


    【解决方案1】:

    您可以使用 jQuery ajaxStart 和 ajaxStop。这些将在发出 ajax 请求时全局运行,因此 fetch 和 save 将导致它们运行。添加代码以在开头显示微调器并在最后隐藏它。

    【讨论】:

    • 这一次只处理一个呼叫不是吗?因此,如果我想同时查看多个请求,我就不走运了。
    • 你可以有一个 AJAX 计数器来计算正在进行的请求数,从 0 开始,在 ajaxStart 时递增,在 ajaxStop 时递减。但是你真的想在每次 AJAX 调用时触发它吗,如果它只是一个自动 AJAX 调用来查看是否有任何新通知(即收件箱计数器、新闻提要计数器)。
    • jQuery 已经跟踪当前正在运行的 ajax 请求数。您无需手动跟踪。
    • 如果页面进行其他不相关的ajax调用,这个想法就行不通了。
    【解决方案2】:

    在 Backbone.js 1.0.0 中,您可以使用 requestsync 事件 http://backbonejs.org/#Events-catalog 这在视图中。

        initialize: function(){
            this.items = new APP.Collections.itemCollection();
            this.items.bind('request', this.ajaxStart, this);
            this.items.bind('sync', this.ajaxComplete, this);
        }
    
        ajaxStart: function(arg1,arg2,arg3){
            //start spinner
            $('#item-loading').fadeIn({duration:100});
        },
        ajaxComplete: function(){
            $('#item-loading').fadeOut({duration:100});
        }
    

    这可以为每个集合或每个模型应用这里是微调器的一些 CSS http://abandon.ie/notebook/simple-loading-spinner-for-backbonejs

    【讨论】:

      【解决方案3】:

      Collection::fetch() 启动 (see source code) 时,Backbone 不会触发任何事件,因此您必须重写 fetch 方法。也许是这样的:

      var oldCollectionFetch = Backbone.Collection.prototype.fetch;
      
      Backbone.Collection.prototype.fetch = function(options) {
          this.trigger("fetch:started");
          oldCollectionFetch.call(this, options);
      }
      

      这将覆盖fetch 方法,以便在获取开始时为您提供一个事件。但是,这只会触发特定集合实例上的事件,因此如果您有一堆不同的集合,则必须在每个集合上监听该事件。

      【讨论】:

      • 如果您通读源代码的其余部分,您会注意到 fetch 调用了 sync,然后使用 $.ajax。你不需要听一个主干事件来附加一个微调器,你只需要注意一个 ajax 调用。 jQuery ajaxStart 和 ajaxStop 就是这样做的。 documentcloud.github.com/backbone/docs/…
      • 酷,我不知道 $.ajaxStart/Stop。这很适合用于网络活动指示器。
      • 不,@ryanmarc 使用事件绝对有优势。我为此写了一篇文章,tbranyen.com/post/how-to-indicate-backbone-fetch-progress ... 还要确保您返回原始 fetch 调用,否则原始返回值将丢失。
      • 您真的想在每次 AJAX 调用时触发它吗,如果它只是一个自动 AJAX 调用以查看是否有任何新通知(即收件箱计数器、新闻提要计数器)。
      • 请求、同步和错误事件是什么? backbonejs.org/#Events-catalog - 他们似乎就是为了这个?
      【解决方案4】:

      我在不覆盖主干的情况下这样做的方法是:

      在视图中

      var myView = Backbone.View.extend({
        initialize; function(){
      
          this.$el.addClass('loading');
          collection.fetch(success:function(){
            this.$el.removeClass('loading')
          })
        }
      })
      

      另一种方法是在添加模型时删除加载类,通常你有:

      var myView = Backbone.View.extend({
        initialize; function(){
          _.bindAll(this, 'addAll')
          collection.bind('reset', this.addAll)
      
          this.$el.addClass('loading');
          collection.fetch();
        },
        addAll: function(){
          this.$el.removeClass('loading');
          collection.each(this.addOne);
        }
      })
      

      这些在大多数情况下几乎是相同的,因为加载器确实是为了用户体验,在显示内容之前删除它是有意义的。

      【讨论】:

      • 请注意 - collection.fetch(success, error) 只是 jquery ajax 方法的快捷方式。
      • 您是如何处理“取消”按钮以显示取消加载的?
      【解决方案5】:

      还有一点更新。自 2012 年 12 月 13 日起,已向 Backbone.sync 添加了一个 "request" 事件,该事件在开始向服务器发出请求时触发。自 2012 年 1 月 30 日起,我们还添加了一个 "sync" 事件,该事件会在模型状态与服务器成功同步(创建、保存、销毁)时触发。

      因此,您不需要覆盖或扩展本机 Backbone 的方法。对于侦听“开始/完成获取”事件,您可以将侦听器添加到您的模型/集合中,例如:

      var view = new Backbone.View.extend({
          initialize: function() {
              this.listenTo(this.model, 'request', this.yourCallback); //start fetching
              this.listenTo(this.model, 'sync', this.yourCallback); //finish fetching
          }
      });
      

      【讨论】:

        【解决方案6】:

        您可以在任何模型上创建一个名为 sync 的方法,backbone.js 将调用该方法以进行同步。或者您可以简单地替换方法Backbone.sync. 这将允许您只在源代码中的一处进行更改。

        【讨论】:

          【解决方案7】:

          我在我的主干中使用了NProgress,它是目前功能最好的加载器/微调器。

          var view = Backbone.View.extend({
               initialize: function () {
                    this.items = new APP.Collections.itemCollection();
                    this.items.on('reset', this.myAddFunction, this);
                    NProgress.start();
                    collection.fetch({
                         reset:true,
                         success: function () {
                             NProgress.done(true);
                         }
                    });
                }
          });
          

          【讨论】:

            【解决方案8】:

            使用 Backbone 同步方法, 它会调用每次主干同步方法,不仅获取,保存,更新和删除也

            /* 除了直接 ajax 之外,每个请求都会覆盖同步应用程序 */

            Backbone._sync = Backbone.sync;
            Backbone.sync = function(method, model, options) {
                // Clone the all options
                var params = _.clone(options);
            
            params.success = function(model) {
                // Write code to hide the loading symbol
                 //$("#loading").hide();
                if (options.success)
                    options.success(model);
            };
            params.failure = function(model) {
                // Write code to hide the loading symbol
                 //$("#loading").hide();
                if (options.failure)
                    options.failure(model);
            };
            params.error = function(xhr, errText) {
                // Write code to hide the loading symbol
                 //$("#loading").hide();
                if (options.error)
                    options.error(xhr, errText);
            };
            // Write code to show the loading symbol
                 //$("#loading").show();
            Backbone._sync(method, model, params);
            };
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2018-12-02
              • 1970-01-01
              • 1970-01-01
              • 2021-11-03
              • 2016-12-26
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多