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');
}
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.
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.)
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....
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.