我正在尝试创建一些从服务器获取数据的组合框。 它们都相同,但数据不同。这是我的MainView的渲染功能:
render: function () {
...
this.$el.append(this.template(this.options));
this.$('#Type').append(new App.Views.TicketTypes({ collection : new App.Models.TicketTypes() }).render().el);
this.$('#Priority').append(new App.Views.Priorities({ collection : new App.Models.Priorities() }).render().el);
this.$('#Status').append(new App.Views.Statuses({ collection : new App.Models.Statuses() }).render().el);
this.$('#State').append(new App.Views.States({ collection : new App.Models.States() }).render().el);
return this;
}
这是主模板:
<label class="text-center">{{Type}}</label>
<br>
<div id="Type" class="form-group">
</div>
<label class="text-center">{{Priority}}</label>
<br>
<div id="Priority">
</div>
<label class="text-center">{{Status}}</label>
<br>
<div id="Status">
</div>
<label class="text-center">{{State}}</label>
<br>
<div id="State">
</div>
<br>
这是我定义的观点:
App.Views.SelectList = Backbone.View.extend({
template: templates.SelectList,
collection : null,
initialize: function (options) {
if (options) {
this.collection = options.collection;
}
},
render: function () {
this.el.innerHTML = this.template(this.options);
thiz = this;
this.collection.fetch({beforeSend :App.Auth , success : function (collection , response) {
collection.each(function (item) {
thiz.$('select').append("<option>" + item.get('Text') + "</option>");
} , this);
}});
return this;
}
});
App.Views.TicketTypes = App.Views.SelectList.extend();
App.Views.Priorities = App.Views.SelectList.extend();
App.Views.Statuses = App.Views.SelectList.extend();
App.Views.States = App.Views.SelectList.extend();
这是SelectList Template:
<select class="form-control">
</select>
<br>
我的所有模特都是这样的:
{"id":1,"Text":"Netowrk"}
正如你所看到的只有最后一个gots数据,令人惊讶的是所有模型的所有数据都进入了最后一个。看到这里:
我知道如果我改变了这个渲染功能:
render: function () {
this.el.innerHTML = this.template(this.options);
thiz = this;
this.collection.fetch({beforeSend :App.Auth , success : function (collection , response) {
collection.each(function (item) {
thiz.$('select').append("<option>" + item.get('Text') + "</option>");
} , this);
}});
return this;
}
到此:
render: function () {
this.el.innerHTML = this.template(this.options);
this.collection.thiz = this;
this.collection.fetch({beforeSend :App.Auth , success : function (collection , response) {
collection.each(function (item) {
collection.thiz.$('select').append("<option>" + item.get('Text') + "</option>");
} , this);
}});
return this;
}
它会解决问题,但有没有更好的方法呢?
感谢。
答案 0 :(得分:2)
你有一个范围问题。这样:
thiz = this;
创建一个全局thiz
变量,以便迭代集合中的每个匿名函数:
collection.each(function (item) {
thiz.$('select').append("<option>" + item.get('Text') + "</option>");
} , this);
最终使用完全相同的thiz
。那些collection.each
调用包含在AJAX调用(this.collection.fetch
)中,JavaScript是单线程的,所以它们都是在第一个执行之前创建的。这意味着所有这些函数将使用完全相同的thiz
,其值将是分配给它的最后thiz = this
。这是伪装的经典封闭问题。
切换到:
this.collection.thiz = this;
您将thiz
范围限定在正确的视图中,一切都按预期工作。
var thiz = this;
// or
let thiz = this;
检查链接文档中的差异。