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

Collection and Model fetching/saving etc status #2185

Closed
g00fy- opened this issue Jan 24, 2013 · 9 comments
Closed

Collection and Model fetching/saving etc status #2185

g00fy- opened this issue Jan 24, 2013 · 9 comments
Labels

Comments

@g00fy-
Copy link

g00fy- commented Jan 24, 2013

To be able to know if the collection was populated, or is beeing populated, there might be something like

collection.fetch();
collection.isFetching()===true; // display loading 

(collection.isFetching()===false; && collection.length) // display no records found

Real usecase (simplification, the objects are passed deep in the system):

// somewhere in the code
collection = new MyCollection();
// somewhere else in the code
view  = new MyView({collection:collection});
// and somewhere else in the code
collection.fetch();

the view listens for collection signals, and displays either loading/no records/records list

for model, there could be even save/delete/update thing

@braddunbar
Copy link
Collaborator

Hi @g00fy-! I would recommend that you use the "request" and "sync" events for this purpose. What do you think?

collection.on('request', function() {
  // loading...
}).on('sync', function() {
  // display records or "none found"
});
collection.fetch();

Edit - I meant the "request" event, not "fetch".

@caseywebdev
Copy link
Collaborator

I think that's a swell idea @braddunbar!

@braddunbar
Copy link
Collaborator

Thanks @caseywebdev! :)

Let us know if that doesn't work for you @g00fy-.

@g00fy-
Copy link
Author

g00fy- commented Jan 24, 2013

@braddunbar , @caseywebdev the idea is to decouple those two parts. (view should be able to get collection in any state, not just 'clean' collection)
I am aware that I can do this using signals, but in many cases this can not be done this way. The order of actions matters

I agree that view should listen for 'request' and 'sync' signals, but the request signal might be sent before the collection is passed to the view, therefore view has no idea that the collection is fetching.

Consider an example, where your view gets an arbitrary collection. This collection can be either fetched , fetching or unfetched when it is passed to the view (tl:dr see example 3).

Example 1 (where signals will work)

collection = new Backbone.Collection();
view = new Backbone.View({collection:collection});
view.render();
// what should the view render ?
collection.fetch() // now sync signal gets sent

Example 2 (view gets already fetched, but emty collection, signals will also work)

collection = new Backbone.Collection();
collection.fetch();  // now sync signal gets sent
// after fetch completes
// view won't be able to receive 'sync' signal
view = new Backbone.View({collection:collection}); 
view.render(); 
// at this point collection.length == 0. 
// I guess the view can listen to 'sync' and then render 'empty' 

Example 3 (most important, signals will not work)

collection = new Backbone.Collection();
collection.fetch();  // now 'request' signal gets sent, but it is pending
// view won't be able to receive 'request' signal
view = new Backbone.View({collection:collection}); // at this point collection.length == 0
// view did not receive the 'request' signal, therefore has no idea that the collection is fetching
// and the view should render  'loading'
// after 2 seconds, 'sync' signal gets sent

View should not assume that if collection.length == 0 then it is unfetched.
View should also not assume that it is given collection in unfetched state (or in any other state).

If we want to decouple collection from view, then view has to be able to know what is the collection state.

the same thing goes for the Model

@caseywebdev
Copy link
Collaborator

@g00fy If you can't just fetch the collection after sending it to the view, set a fetching flag or such on your collection.

collection.on({
  request: function () { this.fetching = true; },
  'sync error': function () { this.fetching = false; }
});

Now your view can access this.collection.fetching and also wait for this.collection to fire the sync or error event.

@g00fy-
Copy link
Author

g00fy- commented Jan 24, 2013

@caseywebdev
The request might be aborted, or two requests might get sent at once.

// example 1
collection.fetch().abort()  // and collection.fetching == true
// example 2 - don't care about abort();
collection.fetch();
collection.fetch();
// 1st request compleated
!!collection.fetching == false // but the 2nd request is pending - should it be loading or not?
// 2nd request completed

The solution to this would be to connect do deferred xhr

collection.on({
    'request':function(model,xhr){ 
        this.fetching = true; 
        xhr.fail(function(){this.fetching = false }.bind(this));
    },
    'sync error': function () { this.fetching = false; }
});

That is why, I think this might be handy to have this built in, but on other hand, if every enhancement like this got through, BB code-base would be bloated.

@caseywebdev
Copy link
Collaborator

if every enhancement like this got through, BB code-base would be bloated.

@braddunbar
Copy link
Collaborator

I think it's less about bloating than it is about approach. There are many different ways you might want to handle concurrent requests. Backbone provides you with the primitives that you need to handle them and then gets out of the way.

@akre54
Copy link
Collaborator

akre54 commented Jan 24, 2013

@g00fy- you might want to take a look into writing a finite-state machine for your purposes. Chaplin.js has one that should be pretty easy to replicate, and there's also ifandelse/machina.js (see the blog post) which may suit your specific use case.

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

No branches or pull requests

4 participants