我有一个骨干视图,我想渲染html AFTER 2异步调用:
initialize: function (model, options) {
team.fetch({
success: function (collection) {
//do some things
});
goal.fetch({
success: function (collection) {
//do some things
});
this.render();
}
render: function () {
this.$el.html(template());
return this;
}
显然,使用上面的代码,html模板将在ajax调用之前/期间返回。通常,当只有一个ajax调用时,我会这样做:
initialize: function (model, options) {
var that = this;
team.fetch({
success: function (collection) {
//do some things
that.render();
});
}
render: function () {
this.$el.html(template());
return this;
}
使用多个ajax调用执行此操作的最佳方法是什么?
答案 0 :(得分:3)
我会使用JQuery Deferred实施,特别是$.when
。这使您只有在完成多个异步操作时才执行操作。像这样使用它:
var ajax1 = team.fetch({ ... });
var ajax2 = goal.fetch({ ... });
$.when( ajax1, ajax2 ).done( this.render );
修改强>
正如@muistooshort指出的那样,你还必须绑定render
,以便使用正确的上下文调用它(否则this
内的render
将引用ajax对象而不是视图对象):
_.bind(this.render, this);
答案 1 :(得分:1)
这样你就可以理解jQuery Deferred正在拯救你的东西,这是一个如何在没有它的情况下解决这个常见问题的例子。 (想象一下,为4个集合/模型编写相同的代码,而不仅仅是2个。)
initialize: function(model, options) {
team.fetch();
goal.fetch();
this.listenTo(team, 'sync', this.teamFetched);
this.listenTo(goal, 'sync', this.goalFetched);
},
teamFetched: function() {
this._teamFetched = true;
// if goal also fetched, call & return this.render()
return (( this._goalFetched ) ? this.render() : this);
},
goalFetched: function() {
this._goalFetched = true;
// if team also fetched, call & return this.render()
return (( this._teamFetched ) ? this.render() : this);
}
render: function() {
this._goalFetched = this._teamFetched = false;
this.$el.html(template());
return this;
}