backbone.js - получение дополнительных данных вместе с запросом - PullRequest
18 голосов
/ 19 апреля 2011

У меня есть коллекция, в которой хранятся некоторые пользователи.Некоторая информация, которая необходима, - это общее количество, количество страниц и т. Д. Как передать их клиенту?Или они должны исходить из отдельного представления, и в этом случае мне понадобится более одного вызова ajax?Я хотел бы иметь коллекцию fetch(), а также получить некоторые из этих «метаданных».Какой хороший способ справиться с этим?

Ответы [ 3 ]

35 голосов
/ 30 апреля 2011

Как правило, вам нужно обработать это в методе parse класса коллекции.Его обязанность - принять ответ и вернуть обратно массив атрибутов модели.Тем не менее, вы можете сделать больше, чем это, если хотите, если вы не возражаете против метода разбора, на котором лежит эта дополнительная ответственность.

UserList = Backbone.Collection.extend({

    model: User,

    url: '/users',

    parse: function(data) {
        if (!data) {
            this.registered_users = 0;
            return [];
        }
        this.registered_users = data.registered_users;
        var users = _(data.users).map(
            function(user_data) {
                var user = {};
                user['name'] = user_data.name;
                return user;
            }
        );
        return users;
    }
});

Так что в приведенном выше простом примере предположим, что сервер возвращает ответ, который содержитколичество зарегистрированных пользователей и массив пользовательских атрибутов.Вы будете и анализировать пользовательские атрибуты, и возвращать их, а также снимать счетчик зарегистрированных пользователей и просто устанавливать его как переменную в модели.
Метод parse будет вызываться как часть выборки.Поэтому нет необходимости изменять выборку, просто используйте встроенный метод хука, который у вас есть.

Пуристы скажут, что вы возлагаете на метод синтаксического анализа вторичную ответственность, которая может удивить некоторых людей (например, вернуть что-то и изменитьмодельное состояние).Тем не менее, я думаю, что это нормально.

1 голос
/ 19 апреля 2011

Один из способов сделать это - переопределить метод Collection::fetch(), чтобы он анализировал эти метаданные из ответа.Вы можете сделать так, чтобы ваш сервер возвращал ответ, подобный этому:

{
    "collection": [
        { ... model 1 ... },
        { ... model 2 ... },
        ...
    ],
    "total_rows": 98765,
    "pages":      43
}

В вашем методе fetch, который переопределяет исходный метод Backbone.Collection::fetch(), вы можете обрабатывать каждое свойство объекта отдельно.Здесь вы можете сделать переопределение с помощью слегка измененного fetch метода:

_.extend(Backbone.Collection.prototype, {
  fetch : function(options) {
    options || (options = {});
    var collection = this;
    var success = options.success;
    options.success = function(resp) {
      // Capture metadata
      if (resp.total_rows) collection.total_rows = resp.total_rows;
      if (resp.pages)      collection.pages      = resp.pages;

      // Capture actual model data
      collection[options.add ? 'add' : 'refresh'](
        collection.parse(resp.collection), options);

      // Call success callback if necessary
      if (success) success(collection, resp);
    };
    options.error = wrapError(options.error, collection, options);
    (this.sync || Backbone.sync).call(this, 'read', this, options);
    return this;
});

Обратите внимание, что этот подход с использованием _.extend затронет все ваши классы, которые расширяют Backbone.Collection.

Таким образом, вам не нужно совершать 2 отдельных вызова на сервер.

0 голосов
/ 27 апреля 2011

Я бы загрузил информацию при создании страницы.Запишите информацию в HTML-документ, когда сервер создает сайт.Например, вам совсем не обязательно звонить по Ajax.Я делаю это со всей коллекцией в ordner, чтобы сначала не загружать страницу, а затем ждать, пока вызов ajax вернет необходимую информацию.

Пример кода с Python:

Строка 64: https://github.com/ichbinadrian/maps/blob/master/python/main.py <- отсюда </p>

Строка 43: https://github.com/ichbinadrian/maps/blob/master/templates/index.html <- сюда </p>

...