【问题标题】:Backbone fetch callback the proper way以正确方式获取骨干网回调
【发布时间】:2013-10-31 18:02:33
【问题描述】:

我的 Backbone 应用程序有一个名为 schedule 的视图,我对在成功和错误时调用正确函数的区别有点困惑,我尝试了下面列出的两种可能,但我没有't有什么区别以及从放置在外部视图中的路由器调用函数的正确方法是什么:

第一种方式:

        require([
            'app/collections/schedule',
            'app/views/schedule'
        ], function(ScheduleCollection, ScheduleView) {

           var scheduleCollection = new ScheduleCollection(),
            scheduleView = new ScheduleView({
                model: scheduleCollection
            });

            scheduleCollection.fetch({
                reset: true,                
                success: function(){
                    scheduleView.successHandler();
                },
                error: function(){
                    scheduleView.errorHandler()
                }
            });
        });

第二种方式

        require([
            'app/collections/schedule',
            'app/views/schedule'
        ], function(ScheduleCollection, ScheduleView) {

           var scheduleCollection = new ScheduleCollection(),
            scheduleView = new ScheduleView({
                model: scheduleCollection
            });

            scheduleCollection.fetch({
                reset: true,                
                success: scheduleView.successHandler(),
                error: scheduleView.errorHandler()                  
            });
        });

在 scheduleView 中

successHandler: function(){
   console.log('success');
}


erroHandler: function(){
   console.log('error');
}

【问题讨论】:

    标签: javascript backbone.js amd


    【解决方案1】:

    还有另一种选择:与其直接引用视图,不如提供集合作为对相关视图的引用并监听相关事件。例如,在相关视图中侦听集合的重置。如果这不是您想要挂钩的事件,则从您的视图可以侦听的成功/错误回调中触发自定义事件。

    这是一个处理重置的示例 - 扩展您的 ScheduleView:

    var ScheduleView = Backbone.View.extend({ 
    
        initialize: function () {
    
            this.listenTo(this.collection, 'reset', this.handleReset);
        },
    
        handleReset: function () {
            // do whatever you need to do here
        }
    };
    
    var scheduleCollection = new ScheduleCollection();
    var scheduleView = new ScheduleView({ collection: scheduleCollection });
    

    以下是与集合中的成功/错误处理程序相关的自定义事件示例:

    var ScheduleCollection = Backbone.Collection.extend({
    
        getResults: function () {
    
            var self = this;
    
            this.fetch({
                reset: true,
                success: function (collection, response, options) {
                    // you can pass additional options to the event you trigger here as well
                    self.trigger('successOnFetch');
                },
                error: function (collection, response, options) {
                    // you can pass additional options to the event you trigger here as well
                    self.trigger('errorOnFetch');
                }
            });
        }
     };
    
    var ScheduleView = Backbone.View.extend({
    
        initialize: function () {
    
            this.listenTo(this.collection, 'successOnFetch', this.handleSuccess);
            this.listenTo(this.collection, 'errorOnFetch', this.handleError);
        },
    
        handleSuccess: function (options) {
            // options will be any options you passed when triggering the custom event
        },
    
        handleError: function (options) {
            // options will be any options you passed when triggering the custom event
        }
    };
    
    var scheduleCollection = new ScheduleCollection();
    var scheduleView = new ScheduleView({ collection: scheduleCollection });
    scheduleCollection.getResults();
    

    以这种方式连接的好处是您可以消除集合对视图的依赖。如果您希望多个视图来监听您的集合(或您的集合模型)上发生的事件,这一点尤其重要,并且对于您的 Backbone 应用程序来说,这是一种更松散耦合的架构。

    【讨论】:

    • 能否举个例子
    • 很高兴详细说明这一点,正是我需要的!
    【解决方案2】:

    第一种方法是正确的,第二种方法是错误的。但是这种方式会最简洁:

    scheduleCollection.fetch({
        reset: true,                
        success: scheduleView.successHandler,
        error: scheduleView.errorHandler
    });
    

    (虽然...来自 OP,但函数 scheduleView.successHandler 不存在,所以这可能是个问题。)

    【讨论】:

    • 您不需要将这些方法绑定到scheduleView 吗?不在console.log 的情况下,但如果这些方法使用this...
    • @nrabinowitz 是的,我相信是的......我一直不太清楚。
    【解决方案3】:

    第二个不起作用的原因是您需要将引用传递给函数,而不是立即执行。

    var foo = myFunction(); // foo is set to myFunction's return value
    var bar = myFunction; // bar is set to a REFERENCE to myFunction
    
    foo === bar // FALSE
    bar === myFunction // TRUE
    

    更正的代码:

    scheduleCollection.fetch({
        reset: true,                
        success: scheduleView.successHandler,
        error: scheduleView.errorHandler                  
    });
    

    现在,如果您想更进一步,使用返回的 XHR 对象的 jQuery promise API 关闭在各个方面都非常出色,并且不再需要回调。

    scheduleCollection.fetch({ reset: true })
        .then(scheduleView.successHandler, scheduleView.errorHandler);
    

    不同之处在于您会得到一个可以传递的承诺......但这是另一个帖子的主题。 (无耻的插头)查看adamterlson.com 了解我关于承诺的三部分系列......

    【讨论】:

    • 我真的很喜欢 promise 解决方案,代码从左到右读起来很漂亮。我将采用 jQuery Promise 作为我的骨干提取等方面的最佳实践。
    【解决方案4】:

    您需要做的是将函数对象分配给“成功”和“错误”,而不是函数的返回值。 当你这样做时:

    function(){...}
    

    它返回一个函数对象,因此 成功:函数(){...}

    是对的,但如果

    a = function(){...}
    

    你做a() 它执行函数并返回返回值,因此 success: a() 是错误的,但 success: a 是正确的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-07
      • 1970-01-01
      • 2013-01-18
      • 1970-01-01
      相关资源
      最近更新 更多