Как обрабатывать отношения в backbone.js

Я застрял в том, как создать мое приложение backbone.js в отношении моих модельных отношений.

Если у меня есть модель событий, у которой есть пара отношений, скажем, что пользовательская модель может иметь много событий, а модель события, в свою очередь, может иметь много комментариев и участия. Пользователь может иметь много комментариев, и участие может иметь один пользователь и одно событие. Вау, какой беспорядок!

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

Okey, поэтому я подумал, что нужно загрузить список событий, когда пользователь загружает страницу, а когда пользователь нажимает на загрузку события остальную информацию об этом событии (комментарии, участие и пользователь).

Итак, вопрос в том, должен ли я использовать какую-то глобальную переменную для хранения всех событий, пользователей и т.д., и когда я беру информацию с сервера, поставьте ее туда (и проверьте там до того, как я возьму что-нибудь с сервера) возможно, в каком-то локальном хранилище (и как мне это сделать с использованием базового реляционного?).

Еще одна идея, которую я получил, - позволить каждому событию иметь свои собственные независимые данные, проблема в том, что я, вероятно, буду отправлять избыточные данные каждый раз, когда я нажимаю на событие.

Каким образом вы рекомендуете?

спасибо!

Ответ 1

Как и комментарий @mu_is_too_short, Backbone-relational может быть чем-то интересным для изучения. С помощью 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
});

Когда вы создаете реляционную модель Backbone, она автоматически создает набор подмоделей для вас, названный в честь "ключа", который вы назначаете. Таким образом, каждый пользователь, у вас есть, будет иметь собственную коллекцию связанных событий, очищенных.

В принципе, когда вы создаете или выбираете пользователя, вы даете ему ссылки на соответствующие модели, которые ему нужны. Например, для вашего пользователя id = 1 может понадобиться событие 5, 7 и 11. (Я просто использую идентификаторы). Пока эти ссылки определены в форме массива, вы можете лениво загрузить их с помощью методов Relational 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
});

Etc. Etc.

Это хороший способ создания одного к одному, от одного до многих и обратных отношений. Это довольно важно. Когда вы определяете взаимосвязь между моделями и создаете модель.

например. вы создаете новый экземпляр модели пользователя.

Backbone-relational автоматически создает обратную ссылку (модель события имеет атрибут, определяемый ключом обратного отношения "принадлежит TOUser" (или тем, что вы назовете им). Это делает его довольно удобным для перемещения вверх и вниз по модели/подмодули иерархия.

Основываясь на ваших реляционных потребностях, это кажется хорошим подспорьем.

Если вы хотите многих-многих, существует круглый способ сделать это (используя промежуточные модели), но я обнаружил, что это неловко, и я избегаю этого. Paul-Uithol в течение некоторого времени обновляет Backbone-Relational, и новые функции продолжают добавляться. Кривая обучения была для меня немного сложной, но как только вы начнете привыкать к ней, она может оказаться полезной.

ПРИМЕЧАНИЕ. Чтобы подчеркнуть, Моссельман рекомендовал Require.js, и я также очень согласен с этим. Это сделало мой код намного более управляемым. Вы можете переделать (обернуть) речевой код Backbone, чтобы сделать его совместимым с AMD, и он безупречно работает с Require.

UPDATE: backbone-relational теперь поддерживает require.js с момента выпуска 0.8.8 1 апреля 2014 года - спасибо Kenneth

Ответ 2

Вы могли бы теоретически загрузить все отдельные коллекции, а затем использовать локальную фильтрацию в коллекциях, чтобы захватить соответствующие модели при выполнении рендеринга.

Конечно, вы должны учитывать проблемы безопасности.

Я был не совсем ясен, по крайней мере, по вашему вопросу, что вы собираетесь делать с информацией, которую вы получаете, но я постараюсь ответить как можно лучше.

Мое предположение заключается в том, что у вас есть какие-то события с некоторыми дополнительными данными, и вам нужно отобразить информацию, связанную с этим. Затем вам также нужно иметь возможность делать такие вещи, как добавление комментариев и т.д.

Как я уже сказал, вы можете подумать о следующем:

var Events = Backbone.Collection.extend({
    url: '/events', // You might want to let the app return only an account 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 для людей. Бесстыдно ссылаясь на ответ, который я дал сегодня, проверьте это, это облегчит жизнь независимо от того, что: Дизайн магистральной сети