【问题标题】:How to wait fetch in each-loop如何在每个循环中等待获取
【发布时间】:2016-12-22 12:17:04
【问题描述】:

我希望每个项目都从服务器获取数据,然后创建一个包含这些数据的组合框。现在发生的事情是我得到了 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
        });

【问题讨论】:

    标签: javascript jquery backbone.js kendo-ui


    【解决方案1】:

    在我看来,问题在于您总是为self 对象赋值。 success 方法的代码是异步执行的。 因此,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,
        });
    }
    

    【讨论】:

    • 嗨,你的建议奏效了......谢谢和最好的问候
    【解决方案2】:

    您以错误的方式解决问题。您没有按照应有的方式使用所有 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 = [];
        }
    });
    

    【讨论】:

      猜你喜欢
      • 2021-02-04
      • 1970-01-01
      • 2023-01-20
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 2019-04-15
      • 2019-05-22
      • 2021-06-21
      相关资源
      最近更新 更多