如何在每个循环中等待获取

时间:2016-12-22 12:17:05

标签: javascript jquery backbone.js kendo-ui

我希望每个项目从服务器提供数据,然后创建一个包含此数据的组合框。现在发生的事情是我有3个具有相同数据的组合框。

我有这段代码:

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
        });

2 个答案:

答案 0 :(得分:0)

对我来说,问题似乎是你总是为self对象赋值。 成功方法的代码是异步执行的。 因此,在每个成功方法调用中都会覆盖self对象的值。

我建议尝试摆脱成功方法中的self引用。像

这样的东西
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,
    });
}

答案 1 :(得分:0)

你正以错误的方式接近问题。你应该尝试在回调中对所有内容进行硬编码,而不是使用所有Backbone。这是callback hell

您要做的是渲染一个集合。在Stack Overflow上有很多关于渲染列表/集合的问题,这里有一些我自己的答案,以列表渲染为例:

我将尝试演示如何在渲染之前获取每个。

将url放在它所属的位置,进入集合类。

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

将项目呈现逻辑包装到视图中

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();
    },
});

还将列表渲染包装在视图中

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 = [];
    }
});