agconti
agconti

Reputation: 18113

Backbone: Referencing collections in the app level view

Consider the Backbone app listed below. When its started, it creates a restaurants collection and view of local restaurants in the users area. The user can later change their search area and then update the entire collection by submitting a search form.

The Problem: How can I reference the collection in the search method if it isn't related to the view?

Currently, I'm setting the restaurant collection and view as properties of the App view itself so that it can be easily referenced from within the method, but this seems in appropriate because the view isn't solely related to that collection.

Is it better to reference the collection as I have or is it better to reference it as App.collection, as backbone does when you in create views realted to collections with Backbone.View.extend({collection: mycollection})?

App view:

 var App = new (Backbone.View.extend({
      
      ...
      
      events: {
        submit: "search",
      },
      start: function(){
        App.render();
        App.restaurants = new App.Collections.Restaurants();
        App.restaurantsView = new App.Views.Restaurants({collection: App.restaurants});
        App.restaurants.fetch({});
      },
      search: function(e){
        e.preventDefault();
        var payload = $( App.targets.searchForm ).serializeObject();
        App.restaurants.fetch({data: payload, processData: true,});
      },

      ...
   
}):

Upvotes: 0

Views: 36

Answers (1)

Mike Stapp
Mike Stapp

Reputation: 626

Those are big questions: How to structure a Backbone application, how to define and maintain module boundaries, and how to decouple modules while allowing notifications where needed, like between search and restaurants?

Big-picture answer: Look at something like Marionette. It's a framework built on top of Backbone, it makes it easy to follow a lot of best practices, and it does some heavy lifting for you. David Sulc has an excellent book about Marionette that covers all of those topics & more. Highly recommended.

Immediate-problem answer: Directly referencing objects outside of a single module (like search) is a bad idea. It couples together concerns that should be kept separate. At a minimum, think of adding an application-level event bus: search can trigger a search event, and the restaurant code can listen for that event and act on its collection in response. You could use something like the backbone.wreqr library's EventAggregator class, which is tailor-made for this kind of thing. In a pinch, you could use an instance of Backbone.Events to roll your own:

App.vent = _.extend( {}, Backbone.Events );

Trigger an event from search code like so:

App.vent.trigger('search', payload);

And in your start function, register to listen for that event:

App.vent.on('search', function(payload) {
    App.restaurants.fetch({data: payload, processData: true,});
});

Upvotes: 2

Related Questions