Listen to a specific attribute changes in a model in a nested collection in Backbone
Asked Answered
A

2

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)

Auscultate answered 27/4, 2013 at 10:7 Comment(0)
R
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

Roundup answered 28/4, 2013 at 7:10 Comment(0)
B
-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.

Bencher answered 28/4, 2013 at 13:56 Comment(3)
Sorry, I don't see how this works. Collection.models is a raw Array, and Array doesn't have an on method. Am I missing something?Landwehr
@ericosoco is right, this doesn't work and I don't see how it could work.Fateful
Agreed - I think this should be updated to be "this.order_collection.on" rather than .models.on.Heteroecious

© 2022 - 2024 — McMap. All rights reserved.