-1

I want for each item to bring data from server then create a combo box containing this data. What is going on now is I got 3 combo boxes with same data.

I have this code:

self.CollectionTest.each(function(item, index) {
    if (item.attributes.QuesAnswerType == 7) {
        self.dtype = item.attributes.QuesAnswerValue_Para;
        self.dropdowncollection = new QuestionaireDetailsCollection;
        self.dropdowncollection.fetch({
            reset: true,
            url: 'api/Variables/getPara',
            data: $.param({ type: self.dtype }),
            success: function() {
                self.dropdowndataSource = new kendo.Backbone.DataSource({
                    collection: self.dropdowncollection,
                });

                var cbid = "cb" + item.attributes.Id;
                $('<input id="' + cbid + '" dataTextField: "Name" dataValueField: "Id" data-bind="value:QuesDetAnswer"/>')
                    .appendTo("#divrb" + item.attributes.Id)
                    .kendoDropDownList({
                        dataTextField: "Name",
                        dataValueField: "Id",
                        dataSource: self.dropdowndataSource,
                        autoBind: true,

                    });
            } // end of success
        });
Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
Lili
  • 21
  • 4

2 Answers2

0

To me it seems that the problem is that you are always assigning values to the self object. The code of the success method is executed asynchronously. Therefore the values of the self object get overridden in every success method call.

I would recommend trying to get rid of the self reference in the success method. Something like

var dropdowncollection = new QuestionaireDetailsCollection;
dropdowncollection.fetch({reset: true, url: 'api/Variables/getPara', data: $.param({ type: self.dtype }), success: function () {
    var dropdowndataSource = new kendo.Backbone.DataSource({
        collection: self.dropdowncollection,
    });

    var cbid = "cb" + item.attributes.Id;
    $('<input id="' + cbid + '" dataTextField: "Name" dataValueField: "Id" data-bind="value:QuesDetAnswer"/>')
    .appendTo("#divrb" + item.attributes.Id)
    .kendoDropDownList({
        dataTextField: "Name",
        dataValueField: "Id",
        dataSource: dropdowndataSource,
        autoBind: true,
    });
}
brass monkey
  • 5,841
  • 10
  • 36
  • 61
0

You're approaching the problem the wrong way. Instead of using all of Backbone as it should, you're trying to hard-code everything in callbacks. This is callback hell.

What you're trying to do is to render a collection. There's a lot of questions about rendering list/collection on Stack Overflow, here's some of my own answers which have a list rendering as an example:

I'll try to demonstrate how to fetch each before rendering.

Put the url once where it belongs, into the collection class.

var QuestionaireDetailsCollection = Backbone.Collection.extend({
    url: 'api/Variables/getPara',
});

Wrap the item rendering logic into a view

var ItemView = Backbone.View.extend({
    template: _.template('<input id="cb<%= Id %>" dataTextField="Name" dataValueField="Id" data-bind="value:QuesDetAnswer"/>'),
    id: function() {
        return "divrb" + this.model.id;
    },
    initialize: function() {
        // let the item view handle the collection
        this.collection = new QuestionaireDetailsCollection();

        this.listenTo(this.collection, 'sync', this.onSync);

        this.collection.fetch({
            reset: true,
            data: $.param({ type: this.model.get('QuesAnswerValue_Para') }),
        });
    },
    render: function() {
        this.$input = $(this.template({ Id: this.model.id }))
        this.$el.html(this.$input);

        this.$input.kendoDropDownList({
            dataTextField: "Name",
            dataValueField: "Id",
            dataSource: this.dropdowndataSource,
            autoBind: true,
        });
        return this;
    },
    onSync: function() {
        this.dropdowndataSource = new kendo.Backbone.DataSource({
            collection: this.collection,
        });

        this.render();
    },
});

Also wrap the list rendering in a view

var ListView = Backbone.View.extend({
    initialize: function() {
        this.childViews = [];
        this.quesAnswerType = 7;
        this.listenTo(this.collection, 'sync', this.render);
    },
    render: function() {
        this.$el.empty();

        // filter the models before rendering
        _.each(this.collection
            .where({ 
                QuesAnswerType: this.quesAnswerType
            }), this.renderItem, this);
        return this;
    },
    renderItem: function(model) {
        var view = new ItemView({ model: model });
        this.childViews.push(view);
        this.$el.append(view.render().el);
    },

    cleanup: function() {
        // avoid memory leaks
        _.invoke(this.childViews, 'remove');
        this.childViews = [];
    }
});
Community
  • 1
  • 1
Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129