我有以下问题...
MyView
与两个观看次数相关联:TaskModel
和UserModel
TaskModel = {id: 1, taskName: "myTask", creatorName: "myName", creator_id: 2 },
UserModel = {id: 2, avatar: "someAvatar"}
视图应显示
{{taskName}}, {{creatorName}}, {{someAvatar}}
正如您所看到的那样TaskModel
和UserModel
的提取应该同步,因为userModel.fetch
需要taskModel.get("creator_id")
您建议我使用哪种方法来显示/处理视图和两个模型?
答案 0 :(得分:10)
你可以让视图足够智能,直到它拥有所需的一切,才能渲染。
假设您有一个用户和一个任务,并将它们都传递给视图的构造函数:
initialize: function(user, task) {
_.bindAll(this, 'render');
this.user = user;
this.task = task;
this.user.on('change', this.render);
this.task.on('change', this.render);
}
现在您有一个视图,它既引用了用户又引用了任务,并且正在监听两者上的"change"
个事件。然后,render
方法可以询问模型是否具有它们应具有的所有内容,例如:
render: function() {
if(this.user.has('name')
&& this.task.has('name')) {
this.$el.append(this.template({
task: this.task.toJSON(),
user: this.user.toJSON()
}));
}
return this;
}
所以render
会等到this.user
和this.task
完全加载后再填充正确的HTML;如果在加载模型之前调用它,则它不呈现任何内容并返回空占位符。这种方法可以将所有视图的逻辑很好地隐藏在它所属的视图中,并且很容易概括。
演示:http://jsfiddle.net/ambiguous/rreu5jd8/
你也可以使用下划线isEmpty
(mixed into Backbone models)而不是检查特定属性:
render: function() {
if(!this.user.isEmpty()
&& !this.task.isEmpty()) {
this.$el.append(this.template({
task: this.task.toJSON(),
user: this.user.toJSON()
}));
}
return this;
}
假设您当然没有任何默认值。
答案 1 :(得分:5)
jQuery的延迟在这里工作得很好。作为一个粗略的例子:
var succesFunction = function () {
console.log('success');
};
var errorFunction = function () {
console.log('error');
};
$.when(taskModel.fetch(), userModel.fetch()).then(successFunction, errorFunction);
您还可以使用原始数据来管道请求(请记住fetch
,save
,create
实际上只是围绕jQuery的$.ajax
对象的包装。
var taskModelDeferred = taskModel.fetch();
var userModelDeferred = taskModelDeferred.pipe(function( data ) {
return userModel.fetch({ data: { user: data.userId }});
});
注意: Backbone在集合和模型上默认返回成功/错误函数中的集合和模型,因此如果您需要,请务必提供参考。
答案 2 :(得分:1)
我遇到了一个使用两个模型和多个视图的复杂布局问题。为此,我只使用一个模型的“成功”函数来调用另一个模型的获取,而不是尝试同步提取。我的观点只会听取第二种模式的变化。例如:
var model1 = Backbone.Model.extend({
...
});
var model2 = Backbone.Model.extend({
...
});
var view1 = Backbone.View.extend({
...
});
var view2 = Backbone.View.extend({
...
});
model2.on("change",view1.render, view1);
model2.on("change",view2.render, view2);
则...
model1.fetch({
success : function() {
model2.fetch();
}
});
要点是你不必进行任何复杂的同步。您只需级联提取并响应最后一个模型的提取。