Tom Brunoli
Tom Brunoli

Reputation: 3466

Backbone-relational functions on collections

I am doing a somewhat large backbone based web app, and I am using backbone-relational. I was wondering if I could have a custom function on the one-to-many relations.

I.E. If I have a country model and it is related to multiple metadata models (each witha type attribute), and I wanted to make a function to filter the related collection down to a certain type. This isn't the best example (I don't want to publicly mention the details of the project), but here's some example code I made (it may not be 100% correct but it gets the idea through):

var Country = Backbone.RelationalModel.extend({

  relations: [
    {
      type: Backbone.HasMany,
      key: 'metas',
      relatedModel: Metadata,
      collectionType: MetadataCollection,
      reverseRelation: {
        key: 'country',
        includeInJSON: '_id'
      }
    }
  ]

});

var Metadata = Backbone.RelationalModel.extend({

  subModelTypes: {
    'landmark' : 'Landmark',
    'city' : 'City'
  }

});

var Landmark = Metadata.extend({});
var City = Metadata.extend({})

var MetadataCollection = Backbone.Collection.extend({

  model: Metadata,

  filterType: function(type){
    this.filter(function(meta){
      return meta.get('type') === type;
    })
  }

});

var Countries = Backbone.Collection.extend({

  model: Country

})

var countries = new Countries([
  {
    name: 'Australia',
    metas: [
      {
        type: 'landmark',
        name: 'Uluru'
      },
      {
        type: 'landmark',
        name: 'Sydney Opera House'
      },
      {
        type: 'city',
        name: 'Sydney'
      }
    ]
  }  
]);

countries.get(1).get('metas').filterType('landmark')
// TypeError: Object [object Object] has no method 'filterType'

Does anyone know if you can do this? If there is another good way to do this (while still keeping the different types in the same collection), I'd love to know.

Thanks!

Upvotes: 3

Views: 628

Answers (1)

Michael Cordingley
Michael Cordingley

Reputation: 1525

The general pattern to create a separate object to act as a proxy for your collection. The proxy contains a reference to the base collection and its own collection that contains the reduced set. This proxy then listens to events on the base collection and updates the filtered collection accordingly, forwarding events as appropriate. With this in place, you add, update, and remove models as normally from the base collection, let the proxy update itself as necessary, and wire up your view or whatever is consuming the filtered collection to the proxy.

As doing that manually is a bit of a pain and error-prone, I'd recommend using this library: https://github.com/jmorrell/backbone.obscura

If you're familiar with the concept of a View within a relational database, this is the same idea.

Upvotes: 1

Related Questions