11

モデルの関係に関して backbone.js アプリケーションを設計する方法に行き詰まっています。

いくつかの関係を持つ event model がある場合、ユーザー モデルには多くのイベントを含めることができ、イベント モデルには多くのコメントと参加を含めることができます。ユーザーは多くのコメントを持つことができ、参加は 1 人のユーザーと 1 つのイベントを持つことができます。うわー、なんて混乱!

Event has many Comments
Event has many Participations
Event has one User

User has many Events
User has many Participations
User has many Comments

Comment has one Event
Comment has one User

Participation has one User
Participation has one Event

わかりましたので、ユーザーがページをロードしたときにイベントのリストをロードし、ユーザーがイベントをクリックすると、そのイベントに関する残りの情報 (コメント、参加、ユーザー) をロードすることを考えました。

問題は、ある種のグローバル変数を使用してすべてのイベント、ユーザーなどを保持する必要があるか、サーバーから情報を取得するときにそこに配置する必要があるか (そして、サーバーから何かを取得する前にそこをチェックするか)、おそらくいくつかの場合です。一種のローカルストレージ (バックボーンリレーショナルを使用してこれを行うにはどうすればよいですか?)。

私が持っていた別のアイデアは、すべてのイベントに独自の独立したデータを持たせることです.これの問題は、イベントをクリックするたびに冗長なデータを送信する可能性があることです.

どのような方法をお勧めしますか?

ありがとう!

4

2 に答える 2

18

@mu_is_too_short がコメントしたように、Backbone-relational はあなたが興味を持っているものかもしれません。バックボーン リレーショナルを使用すると、モデルとサブモデル コレクションが自動的に作成され、親子関係全体でイベントを管理できます。

サンプル コードをいくつか示します。サンプル コードの一部は次のようになります。

ユーザーには多くのイベントがあります:

User = Backbone.RelationalModel.extend({
    relations: [
        type: Backbone.HasMany,   // Type of relationship
        key: 'events',            // How we reference the sub-models in collection
        relatedModel: 'Event',    // The sub-model type
        collectionType: 'EventCollection',  // The sub-model collection
        reverseRelation: {
            key: 'belongsToUser'            // Key we use to refer to the parent
        }
    ],
    // Other Backbone.Model properties and functions
});

バックボーン リレーショナル モデルを作成すると、指定した「キー」に基づいて名前が付けられたサブモデルのコレクションが自動的に作成されます。したがって、所有している各ユーザーには、整理された関連イベントの独自のコレクションがあります。

基本的に、ユーザーを作成または取得するときに、必要な関連モデルへの参照を与えます。たとえば、User id=1 には Event 5、7、および 11 が必要になる場合があります (ID を使用しているだけです)。これらの参照が配列形式で定義されている限り、リレーショナルの fetchRelated メソッドを使用して遅延ロードできます。

myUser = new User();
myUser.set({
    name: 'RayMysterio',
    age: '26',
    events: [5, 7, 11]    // Or this might just come with the User object from your server
});

myUser.fetchRelated('events');
// This will go fetch the related events for this user model from the URL you designate.

myUser.get('events');
// The collection of events are treated like an attribute of the User model.

myUser.get('events').find(function(eventModel){
    return // some find condition - or whatever you want to do on that collection
});

特定のリスナーをサブモデルにバインドしたい場合があります。

myUser.bind('add:events', function(model, collection) {
    // Whatever code you want to happen when new models are added to the user events coll
});

などなど

これは、1 対 1、1 対多、および逆の関係を作成する優れた方法です。これはかなり重要です。モデル間の関係を定義し、モデルを作成するとき。

たとえば、User モデルの新しいインスタンスを作成します。

バックボーン リレーショナルは自動的に逆リンクを作成します (イベント モデルには、逆リレーション キー 'belongsToUser' (または任意の名前) で定義された属性があります)。これにより、モデル/サブモデル階層を上下にトラバースするのが非常に便利になります。

あなたのリレーショナル ニーズに基づいて、これは適切なようです。

多対多が必要な場合は、(中間モデルを使用して) 回りくどい方法がありますが、私はこれがちょっと不安定であることがわかったので、避けています。Paul-Uithol はしばらくの間 Backbone-Relational を更新しており、新しい機能が追加され続けています。学習曲線は最初は私にとって少し大変でしたが、慣れ始めると非常に便利です。

注: 強調しておくと、Mosselman は Require.js を推奨しており、私もこれに強く同意します。それは私のコードをより管理しやすくしました。バックボーン リレーショナル コードをいじる (ラップする) ことで、AMD 準拠にすることができ、Require で問題なく動作します。

更新: backbone-relational は、2014 年 4 月 1 日のリリース 0.8.8 で require.js をサポートするようになりました - Kenneth に感謝します

于 2012-06-04T01:29:59.097 に答える
0

理論的には、すべての個別のコレクションをロードし、コレクションでローカルフィルタリングを使用して、レンダリングを行うときに関連するモデルを取得できます。

もちろん、これにはセキュリティの問題を考慮する必要があります。

少なくとも私には、あなたが取得した情報をどうするかという質問からは正確にはわかりませんでしたが、できる限り答えようと思います。

私の仮定では、いくつかの追加データを含むある種のイベントがあり、これに関連する情報を表示する必要があります。次に、コメントの追加などもできる必要があります。

私が言ったように、あなたは次のことを検討することができます:

var Events = Backbone.Collection.extend({
    url: '/events', // You might want to let the app return only an account's events or something, not just ALL events.
    initialize: function(){
        this.fetch();
    }
});

var Comments = Backbone.Collection.extend({
    url: '/comments',
    initialize: function(){
        _.bindAll(this, 'getEventComments');
        this.fetch();
    },

    getEventComments: function(event_id){
        return _.filter(this.models, function(model){ return model.get('event_id') == event_id; });
    }
});
//etc

アンダースコアのフィルター機能を使用すると、必要なときに(レンダリング時などに)関連するモデルをすばやく取得できます。

ある意味で、これはサーバーサイドスクリプトで行うのと同じです。一部のデータベースは、コレクションがここで行うように、レコードを含むすべてのテーブルを保持し、コードは、いくつかの入力に基づいて、関連するテーブルをデータベースに要求するだけです。

最後に、私は常にRequire.jsとBackboneを組み合わせて人々に向けていきます。私が今日与えた答えを恥知らずに参照して、それをチェックしてください、それは何があっても人生を楽にするでしょう: バックボーンデザイン

于 2012-06-03T19:43:09.157 に答える