Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhanced deferreds; issue #1774 #1775

Closed
wants to merge 4 commits into from

Conversation

pmaccart
Copy link

Hi all,

We've been leveraging the Deferred objects returned from Backbone.sync calls extensively in our application, and have found those to be very convenient, particularly when views depend on multiple models.

One case we've struggled with is when we have nested Backbone views, we're forced to provide both the collection instance and deferred object to the child view constructor:

var View1 = Backbone.View.extend({
    render:function () {
        var collection = new Backbone.Collection();
        collection.url = '/path/to/resources';

        var deferred = collection.fetch();
        var subview1 = new Subview1({collection:collection, deferred:deferred}).render();
        this.$el.append(subview1.el);

        deferred.done(this.onCollectionFetched);

        return this;
    },

    onCollectionFetched:function (collection) {
        // do stuff with collection
    }
});

var Subview1 = Backbone.View.extend({
    initialize:function () {
       this.collection = this.options.collection;
       this.deferred = this.options.deferred;
    },

    render:function () {
        this.deferred.done(this.onCollectionFetched);
        return this;
    },

    onCollectionFetched:function (collection) {
        // do stuff with collection
    }
});

The example above is fairly trivial, but quickly becomes complex has the hierarchy grows (particularly if certain views in the hierarchy should not be blocked from rendering based on data not being ready). It would be nice if the deferred would be modified slightly such that the collection (or model) was provided as the first argument to the callbacks:

var View1 = Backbone.View.extend({
    render:function () {
        var collection = new Backbone.Collection();
        collection.url = '/path/to/resources';

        var deferred = collection.fetch();
        var subview1 = new Subview1({deferred:deferred});

        deferred.done(this.onCollectionFetched);

        return this;
    },

    onCollectionFetched:function (collection) {
        // do stuff with collection
    }
});

var Subview1 = Backbone.View.extend({
    initialize:function () {
       this.collection = this.options.collection;
       this.deferred = this.options.deferred;
    },

    render:function () {
        this.deferred.done(this.onCollectionFetched);
        return this;
    },

    onCollectionFetched:function (collection) {
        // do stuff with collection
    }
});

I've attached a pull request to this issue illustrating a potential fix, but am certainly open to suggestions and other approaches to take.

Thanks,
Phil

pmaccart added 4 commits October 25, 2012 17:14
When a Backbone.ajax call is triggered, provide a modified xhr object
as the response to include the object the ajax call was invoked upon as
the first paramter to all callbacks
@wookiehangover
Copy link
Collaborator

Thanks for opening an pull request, @pmaccart. Unfortunately, this is probably better as a plugin or a custom override of Backbone.sync. $.Deferred is jQuery specific (it's not available in zepto), and this would introduce breaking changes to folks relying on the unaltered deferred object.

@pmaccart
Copy link
Author

I suspected as much, but wanted to at least start a discussion around this. In working with a large-scale Backbone application containing upwards of 10's of nested views on single pages, most of which rely on shared pieces of data, it becomes very cumbersome passing collections around and maintaining who fetched what. We've integrated this pull request as an extension on our project, and I'll look at getting this released as a plugin somewhere.

@wookiehangover
Copy link
Collaborator

No problem. Come to think of it, @tbranyen has been working on normalizing deferreds by way of a plugin recently. It's a bit different that what you're getting at, but it might be worth taking a look at as an example of a well organized plugin: https://github.com/tbranyen/backbone.cacheit

Also, the #documentcloud room in freenode IRC is another great place to bounce ideas off of people if you're just looking for input, most of the contributors and heavy users hang out in there regularly.

@pmaccart
Copy link
Author

Awesome -- @tbranyen 's project looks very similar to what we're we're considering implementing. I'll definitely take a look through his Tim's project, and see if we can exchange any insights.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants