Backbone fetch callback the proper way

2019-03-13 08:29发布

My Backbone application has a view called schedule, I am a bit confused about the difference of calling the proper function on success and error, I am tried the both of tow possible listed below but i didn't what is difference and what is the right way to call a function from router placed in outside view:

The first way:

        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()
                }
            });
        });

The second way

        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()                  
            });
        });

in the scheduleView

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


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

4条回答
对你真心纯属浪费
2楼-- · 2019-03-13 08:50

There's another option: rather than referencing the views directly, provide the collection as a reference to the concerned views and listen for relevant events. For example, listen for reset on the collection in the concerned view. If that's not the event you want to hook into, then trigger a custom event from the success/error callbacks that your view can listen to.

Here's an example handling reset - extend your 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 });

here's an example of custom events tied to the success/error handlers from the collection:

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();

The advantage of wiring up this way is you remove the dependency the collection has on the view. This is especially key if you want more than one view to listen for events happening on your collection (or you collection models) and is a more loosely coupled architecture for your Backbone application.

查看更多
时光不老,我们不散
3楼-- · 2019-03-13 08:58

The reason your second one doesn't work is that you need to pass a reference to a function rather than executing it immediately.

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

Corrected code:

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

Now, if you want to get advanced, using the jQuery promise API off of the returned XHR object is superior in every way and callbacks should never be necessary anymore.

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

The difference is that you get a promise back that can be passed on... but that's a topic for a different post. (Shameless plug) Check out adamterlson.com for my three-part series on promises....

查看更多
相关推荐>>
4楼-- · 2019-03-13 09:02

The first way is correct, the second is incorrect. But this way would be most concise:

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

(Although ... from the OP, the function scheduleView.successHandler does not exist, so that could be a problem.)

查看更多
女痞
5楼-- · 2019-03-13 09:16

What you need to do is assign function object to 'success' and 'error' and not the return value of function. When you do:

function(){...}

it returns a function object and hence success: function(){...}

is right but if

a = function(){...}

and you do a() it executes the function and returns the return value and hence success: a() is wrong but success: a is right.

查看更多
登录 后发表回答