简体   繁体   中英

Backbone.js pattern: When to load multiple resources?

Most of the open Backbone.js single–page apps and demos out there seem to deal with one or maybe two different resources and usually populate the collections in questions when initially loading the page.

How do you guys deal with multiple (more than 2 or 3) different resources having their data stored remotely? When do you load the content?

An example which should sound familiar to Rails devs:

A current_user object exists, having has_many associations to Project , Team , Task and Invoice models. My client–side app provides some kind of CRUD functionalities for these models, maybe some additional views to connect stuff, etc., having in total many different views and corresponding routes. I want the user to be able to jump straight to any of these routes by eg pasting a link, let's say /#project/34/invoices , which would require the app to have the Project with ID 34 loaded as well as the invoices connected to this project.

How do people solve this issue, given that you can easily end up having many cases like this within a single app? Are you just loading everything initially

current_user: {
  projects: {
    invoices: {…},
    tasks: {…}
  tasks: {…}
  …
}

which doesn't seem clean to me, or do you have a clever way to always load what you need?

Cheers!

One approach is to load enough at start-up to do most high-level tasks. Thereafter, lower-level tasks might need to perform fetches to get detail-level resources.

In a travel management app, you might establish a session for a user and get the user and any reservations that user has. This would enable you to quickly show reservation summaries without having to make additional server calls.

Requests for more detailed reservation data might require a lower level call. For instance, if I have a flight reservation, I might periodically call for flight status information.

I think the key question revolves around your caching strategy. You need to evaluate how long data can live within your app without needing to be refreshed. If your resources go stale quickly, then they should be fetched when needed.

I'm working on a backbone project that you can take a look at here: http://sourceforge.net/projects/myelin/ but more specifically maybe this model: http://myelin.git.sourceforge.net/git/gitweb.cgi?p=myelin/myelin;a=blob;f=public/javascripts/models/tab.js;h=6b4cb6ad26d2fc12a817ec027b60b2b5ef13f463;hb=HEAD

(a couple of caveats: This is my first project using pretty much all of the technologies I chose to use, so I'm positive I made some design errors. If you notice anything, just send me a note so I can try to fix it! I didn't use the backbone controller, and rolled up my own, but I think in your case, the default controller is exactly what you're looking for.)

Backbone.js is very REST-ish in it's approach to dealing with things. I think if you approach it much the same way as you would in the rails world, then it may become more apparent as to a solid solution.

For example, take a look at the way Backbone does it's routing / controllers: http://documentcloud.github.com/backbone/#Controller-routes

It maps a route to an event, which you can set a listener to. So, in your example route above, you could fire an event, and have your projects controller catch it and execute some stuff.

If you were implementing the example in Rails, your invoices controller would be called, you'd grab the data through your Model, then send that data off to the view to have it rendered. Same idea with backbone (Though it's more code-involved than the rails world).

In my app, that's what's happening. The user does something in the UI, which triggers an event, which is caught and sent off to a controller. The controllers have methods very similar to the names in rails: 'get', 'index', 'create', 'destroy' etc... Once the model has done it's thing, it then calls it's view, and renders, or does whatever it needs to do.

In the example above (tab.js), when a Tab is instantiated, it's TabContents Collection is built, but empty. Which is similar to rails (I think). Rails won't load the whole kit n kaboodle, unless you ask it to.

Hope that helps!

I found a way for myself to handle this — maybe it helps someone else:

I'm extending a base collection class which implements a method isStale . Like this I can fetch or "refresh" the data for a collection if this hasn't been done for a certain time:

if (this.collection.isStale()) {
  this.collection.fetch();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM