18

I have the following backbone structure:

- collection[order_items]
   - collection[menu_items]
        - price
        - quantity

and I want to listen for any changes in the quantity attribute, I got it working by

var CheckoutView = Backbone.Marionette.ItemView.extend({

    template: '#template-checkout',

    initialize: function (options) {
        this.order_collection = options.collection;
        _(this.order_collection.models).each(function (element, index, list) {
            this.listenTo(element.get("menu_items"), "change:quantity", this.onOrderItemsChanged);
        }, this);

    },

    onOrderItemsChanged: function (model, val, options) {
        console.log(model.get("name"));
    }

});

But does marionette or backbone have a better way of doing it, instead of looping throught the parent collection and adding the listener to each child collection, maybe something like

this.listenTo(this.order_collection, "change:menu_items:quantity", this.on OrderItemsChanged)

(which didnt work for me)

machineghost
  • 33,529
  • 30
  • 159
  • 234
Yehia A.Salam
  • 1,987
  • 7
  • 44
  • 93

2 Answers2

6

Take a look at Backbone.DeepModel. Apparently, you can represent Order as a single model with deep structure and listen to either change:order_items.*.menu_items.* or change:order_items.menu_items.*. Note that this solution prevents you from using benefits of nested lists as Backbone.Collection. I think it's a good tradeoff, but your mileage may vary

Alexander Lebedev
  • 5,968
  • 1
  • 20
  • 30
-8

Backbone collection has its own events as Backbone models do. You just have to bind the event in your collection and all the models inside it will listen for it. Eg:

this.order_collection.models.on('change:quantity', function(model, updatedQuantity) {
    alert("Changed quantity from " + model.previous("quantity") + " to " + updatedQuantity););
});

So, events triggered on a model in a collection will also be triggered on the collection.

ricardohdz
  • 579
  • 4
  • 9