0

I have a parent view ProductListView containing multiple child views ProductView in a multi-step wizard. When a user click on a ProductView, its model's id should be stored somewhere (possibly in an array) so that it can be sent back to the server side for processing.

Problem: Where should I store the id of the ProductView that has been clicked by the user? I tried storing it in its parent view ProductListView but cannot seem to access the array selectedProducts in the parent view from the child view ProductView.

Is this the correct approach? How should this be done?

Model

ProductCollection = Backbone.Collection.extend({
    model: Product,
    url: '/wizard'
});

Parent View

ProductListView = Backbone.View.extend({
    el: '#photo_list',

    selectedProducts: {},  // STORING SELECTED PRODUCTS IN THIS ARRAY

    initialize: function() {
        this.collection.bind('reset', this.render, this);
    },

    render: function() {
        this.collection.each(function(product, index){
            $(this.el).append(new ProductView({ model: product }).render().el);
        }, this);
        return this;
    }
});

Child View

ProductView = Backbone.View.extend({
    tagname: 'div',
    className: 'photo_box',

    events: {
        'click': 'toggleSelection'
    },

    template: _.template($('#tpl-PhotoListItemView').html()),

    render: function() {
        this.$el.html(this.template( this.model.toJSON() ));
        return this;
    },

    // ADDS ITS MODEL'S ID TO ARRAY
    toggleSelection: function() {
        this.parent.selectedProducts.push(this.model.id);
        console.log(this.parent.selectedProducts);
    }
});

2 Answers 2

2

I don't think parent is a property of a backbone View type, and you haven't defined it, so there's no way this line is going to work:

this.parent.selectedProducts.push(this.model.id);

It seems like the correct approach would be to add a selected property to the Product model; toggle that property in the click handler. Then, when it's time to submit to the server, collect the IDs by filtering the Products collection for selected items (underscore.js included with Backbone makes this easy).

Sign up to request clarification or add additional context in comments.

1 Comment

I would also take @dbaseman's approach and have each model have a selected attribute. Then at the end you just do collection.filter(function(product){return product.selected === true;}) to get an array of selected products models. You can easily pluck() the ids if you want too. But Backbone being as it is, your way of pushing an array is also not incorrect. Just pass in a reference of your parent view to you child. var childView = new ProductView({'parent': parentView}); and you can access your parentView array.
1

Why not try to keep selected information, directly in model. So, you will be easily tracking change state of selected using events, and use that information on further wizard steps?

toggleSelection: function () {
    this.model.set({ selected: true });
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.