Search code examples
javascripthtmlbackbone.jsunderscore.jslodash

Backbone one to many relationschip


I'm a beginner with Backbone.js and i have trouble to make a one to many relationschip between two Backbone models, and showing this data into a html tabel row. I'm working with a machine that can have multiple orders. the data will look like :

  • machine 10 has orders 1,2,5,9.
  • machine 14 has orders 3,4,6.

The machine and orders are coupled with a FK machine_id in order. I'm trying to make the TR element with the first element TH to be the machine, and on the second/third TH i wanna show the orders that are belong to a machine.

So the questions i ask are :

  • how do i make this one to many relationship, within my backbone model.
  • how do i make this TR element within my underscore template to show orders that belong to a machine.

Below are the models for Order and Machine :

app.Machine = Backbone.Model.extend({
    defaults : {
         machine_id : "",  
         status : "",
         description : "",
    },
});
app.Order = Backbone.Model.extend({
    defaults: {
        order_id: "",
        description: "",
        amount: "",,
        begin_date:"",
        end_date:"",
        machine_id: ""
    },
});
app.MachineList = Backbone.Collection.extend({
    model: app.Machine
});

Views:

 app.MachineView = Backbone.View.extend({
    className: 'MachineRow',
    template: _.template($('#Machine_Template').html()),
    render: function(){
        this.$el.html(this.template(this.model.attributes));
        return this;
    }
});
app.MachineListView = Backbone.View.extend({
    el: '#Machine',

    initialize: function(initialMachine){
        this.collection = new app.MachineList(initialMachine);
        this.render();
    },
    render: function(){
        this.collection.each(function(item){
            this.renderMachine(item);
            filterOrder(item.get('machine_id'));
        }, this);
    },
    renderMachine: function(item){
        var machineView = new app.MachineView({
            model: item
        });
        $(machineView.render().el).appendTo(this.$el)
    }
});

HTML code : will look something like this??

<script id="machine_template" type="text/template">            
        <th>
            <%= machine_id %> //etc
        </th>
        <th>
            <%= order_id %> //etc
        </th>
        <th>
            <%= order_id %> //etc
        </th>
  </script>

Solution

  • Assuming you have a collection of orders called orders, you can do something like:

    let renderData = machineList.map(machine -> {
      return {
        machine: machine,
        orders: orders.where({machine_id: machine.get('id')}
      }
    });
    

    this should give you a structure similar to

    [{
       machine: machineModel1,
       orders: [orderModel1, orderModal2]
    },{
       machine: machineModel2,
       orders: [orderModel3, orderModal4]
    }]
    

    You can now pass this to your template function which iterates over each entry and renders it.