如何在每个循环中等待获取
How to wait fetch in each-loop
我希望每个项目都从服务器获取数据,然后创建一个包含这些数据的组合框。现在发生的事情是我得到了 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
});
对我来说,问题似乎在于您总是为 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,
});
}
您处理问题的方式不对。您没有按应有的方式使用所有 Backbone,而是尝试 hard-code 回调中的所有内容。这是callback hell。
您要做的是渲染 collection。在 Stack Overflow 上有很多关于渲染 list/collection 的问题,这里是我自己的一些答案,以列表渲染为例:
- Rendering Backbone collection from XML data
- Detailed explanation of Backbone using a list example
- Another list example
我将尝试演示如何在渲染之前获取每个。
将 url 放在它所属的位置,放入 collection class。
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 = [];
}
});
我希望每个项目都从服务器获取数据,然后创建一个包含这些数据的组合框。现在发生的事情是我得到了 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
});
对我来说,问题似乎在于您总是为 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,
});
}
您处理问题的方式不对。您没有按应有的方式使用所有 Backbone,而是尝试 hard-code 回调中的所有内容。这是callback hell。
您要做的是渲染 collection。在 Stack Overflow 上有很多关于渲染 list/collection 的问题,这里是我自己的一些答案,以列表渲染为例:
- Rendering Backbone collection from XML data
- Detailed explanation of Backbone using a list example
- Another list example
我将尝试演示如何在渲染之前获取每个。
将 url 放在它所属的位置,放入 collection class。
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 = [];
}
});