9

我有以下问题……</p>

MyView它连接到两个视图:TaskModelUserModel

TaskModel = {id: 1, taskName: "myTask", creatorName: "myName", creator_id: 2 },
UserModel = {id: 2, avatar: "someAvatar"}

视图应该显示

{{taskName}}, {{creatorName}}, {{someAvatar}}

如您所见, fetchTaskModel应该UserModel是同步的,因为userModel.fetch需要taskModel.get("creator_id")

您建议我使用哪种方法来显示/处理视图和两个模型?

4

3 回答 3

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.userthis.task都完全加载后才填充正确的 HTML;如果在加载模型之前调用它,则它不呈现任何内容并返回一个空占位符。这种方法将所有视图的逻辑很好地隐藏在它所属的视图中,并且很容易泛化。

演示:http: //jsfiddle.net/ambiguous/rreu5jd8/


您还可以使用 Underscore isEmpty混合到 Backbone 模型中)而不是检查特定属性:

render: function() {
    if(!this.user.isEmpty()
    && !this.task.isEmpty()) {
        this.$el.append(this.template({
            task: this.task.toJSON(),
            user: this.user.toJSON()
        }));
    }
    return this;​​​​
}

这假设您当然没有任何默认值。

演示:http: //jsfiddle.net/ambiguous/4q07budc/

于 2012-05-21T15:53:20.210 回答
5

jQuery 的 Deferreds 在这里工作得很好。作为一个粗略的例子:

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 在集合和模型上的成功/错误函数中返回集合和模型,所以如果你需要这个,请确保有一个方便的参考。

于 2012-05-21T13:55:38.987 回答
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();
    }
});

关键是您不必进行任何复杂的同步。您只需级联提取并响应最后一个模型的提取。

于 2012-05-22T16:54:59.610 回答