Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly use events in Backbone

Tags:

backbone.js

I am building a three-way selector: companies, departments and users.

enter image description here

I am trying to figure out the best way to structure this in my Backbone app. Here's the current problem I'm having.

Say a user has selected a company. Then, the departments and user collections will be populated and the view will update:

enter image description here

The user can then select a department from the list, which will further refine the user select. This I have working well.

Or, the user can go straight to User list and find a user (without first having to specify a department). In this case, the view for both departments and users needs to update:

  1. The department should become selected on the user's department.
  2. The users should refine to all users in the selected user's department, rather than all user's in the selected company.

I am struggling with the best way to do this. So far, my departments and users collections have a selected property, so that's how I'm maintaining state. Currently I'm doing something like

  • When the user selects a department, the department view
    1. Sets the selected department directly on the departments collection
    2. Triggers an event
    3. The users collection hears the event, clears out any selected user, and triggers another event
    4. The users view hears the event, and re-renders. Since it knows about the departments collection, it knows a department has been selected and that it should refine the users down to the department

I do this because if I had the view only trigger the event (without setting the departments selected property first), I would have a race condition: both the departments and users collections would be responding to the event, and depending on the timing the users may not be properly refined.

The second piece:

  • When the user selects a User (without specifying a department), the user view
    1. Sets the selected user directly on the users collection
    2. Sets the selected department directly on the departments collection (which it knows about)
    3. Triggers an event

and this is where I'm stuck. The departments collection doesn't really need to do anything, since its selected property is already correct; really, its view just needs to re-render. And so does the users' view.

But this is not all, because there are lots of other things that can happen. I feel like it's getting out of control.

  • What's the best to structure this?
  • Am I using events properly?
  • How do you deal with a view that needs to hear about other views and other collections changing?

Update: Should I just use routes to save application state? This may simplify things...

Update 2: This question has been helpful to me. Having a separate model to manage state definitely seems the way to go.

Update 3: Having a separate model to store state + the use of jQuery deferreds is amazing. Seriously. It completes me.

like image 934
Sam Selikoff Avatar asked Nov 03 '22 21:11

Sam Selikoff


1 Answers

I find it useful to use a model for keeping track of the state. That way you can pass that model around to different views and don't have views referencing each other directly.

You can use built-in and custom events on the state model to manage state transitions.

In your case collections would not need to store selected. Instead selectedUser and selectedDepartment could be attributes of the state model. Then you could have logic in your model that triggers custom events ('update:users:view' or 'update:departments:view') depending on what is selected.

I hope that makes sense.

like image 121
lanan Avatar answered Nov 09 '22 10:11

lanan