9

I have the following problem…</p>

MyView which is connected to two views: TaskModel and UserModel

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

The view should display

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

As you can see the fetch of TaskModel and UserModel should be synchronized, because the userModel.fetch needs of taskModel.get("creator_id")

Which approach do you recommend me to display/handle the view and the two models?

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の両方が完全にロードされるまで待ってから、適切な HTML に入力します。モデルがロードされる前に呼び出された場合、何もレンダリングせず、空のプレースホルダーを返します。このアプローチでは、ビューのすべてのロジックが、それが属するビュー内にうまく隠され、簡単に一般化できます。this.userthis.task

デモ: http://jsfiddle.net/ambiguous/rreu5jd8/


特定のプロパティをチェックする代わりに、アンダースコアisEmpty(バックボーン モデルに混在) を使用することもできます。

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 の Deferred がうまく機能します。大まかな例として:

var succesFunction = function () {
    console.log('success');
};
var errorFunction = function () {
    console.log('error');
};

$.when(taskModel.fetch(), userModel.fetch()).then(successFunction, errorFunction);

fetchまた、未加工のデータを使用してリクエストをパイプすることもできます ( 、savecreateは、実際には jQuery の$.ajaxオブジェクトの単なるラッパーであることを思い出してください。

var taskModelDeferred = taskModel.fetch();
var userModelDeferred = taskModelDeferred.pipe(function( data ) {
    return userModel.fetch({ data: { user: data.userId }});
});

注:バックボーンは、デフォルトでコレクションとモデルの成功/エラー関数でコレクションとモデルを返すため、これが必要な場合は参照を手元に用意してください。

于 2012-05-21T13:55:38.987 に答える
1

2 つのモデルと複数のビューを使用する複雑なレイアウトで、これとまったく同じ問題に遭遇しました。そのために、フェッチを同期しようとする代わりに、一方のモデルの「成功」関数を使用して、もう一方のフェッチを呼び出しました。私の見解では、2 番目のモデルの変更のみに耳を傾けます。例えば:

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 に答える