21

I've run into a headache with Backbone. I have a collection of specified records, which have subrecords, for example: surgeons have scheduled procedures, procedures have equipment, some equipment has consumable needs (gasses, liquids, etc). If I have a Backbone collection surgeons, then each surgeon has a model-- but his procedures and equipment and consumables will all be plain ol' Javascript arrays and objects after being unpacked from JSON.

I suppose I could, in the SurgeonsCollection, use the parse() to make new ProcedureCollections, and in turn make new EquipmentCollections, but after a while this is turning into a hairball. To make it sensible server-side there's a single point of contact that takes one surgeon and his stuff as a POST-- so propagating the 'set' on a ConsumableModel automagically to trigger a 'save' down the hierarchy also makes the whole hierarchical approach fuzzy.

Has anyone else encountered a problem like this? How did you solve it?

Elf Sternberg
  • 16,129
  • 6
  • 60
  • 68

3 Answers3

15

This can be helpful in you case: https://github.com/PaulUithol/Backbone-relational

You specify the relations 1:1, 1:n, n:n and it will parse the JSON accordingly. It also create a global store to keep track of all records.

Julien
  • 9,216
  • 4
  • 37
  • 38
  • 3
    [Ligament.js](https://github.com/dbrady/ligament.js) is another possible solution. – user240515 May 03 '11 at 17:56
  • Backbone-relational is almost entirely the answer to my dreams. I was headed down that road early on, but this is better thought-out and more elegant. – Elf Sternberg May 03 '11 at 19:14
4

So, one way I solved this problem is by doing the following:

  1. Have all models inherit from a custom BaseModel and put the following function in BaseModel:

        convertToModel: function(dataType, modelType) {
            if (this.get(dataType)) {
                var map = { };
                map[dataType] = new modelType(this.get(dataType));
                this.set(map);
            }
        }
    
  2. Override Backbone.sync and at first let the Model serialize as it normally would:

    model.set(response, { silent: true });

  3. Then check to see if the model has an onUpdate function:

                if (model.onUpdate) {
                    model.onUpdate();
                }
    
  4. Then, whenever you have a model that you want to generate submodels and subcollections, implement onUpdate in the model with something like this:

            onUpdate: function() {
                this.convertToModel('nameOfAttribute1', SomeCustomModel1);
                this.convertToModel('nameOfAttribute2', SomeCustomModel2);
            }
    
Jeff Whelpley
  • 569
  • 1
  • 5
  • 11
2

I would separate out the different surgeons, procedures, equipment, etc. as different resources in your web service. If you only need to update the equipment for a particular procedure, you can update that one procedure.

Also, if you didn't always need all the information, I would also lazy-load data as needed, but send down fully-populated objects where needed to increase performance.

Dan
  • 885
  • 6
  • 11
  • 2
    I just want to comment that your suggestion, while laudable, defeats the purpose of a RESTful interface, in which the coarse document (in this case, Procedure) is passed back-and-forth between the server and the client. – Elf Sternberg May 26 '11 at 23:25