Кэширование коллекций в backbone.js? - PullRequest
9 голосов
/ 12 декабря 2011

Как лучше всего обеспечить, чтобы моя коллекция оставалась в кэше и, таким образом, извлекалась только один раз?

Должен ли я реализовать какой-либо слой кэша?Должен ли я использовать переменную Collection там, где это необходимо?Могу ли я доверять настройке JQuerys AJAX?($.ajaxSetup ({ cache: true });)

Основная коллекция, как она выглядит сейчас:

theCollection = Backbone.Collection.extend({
    model: theModel,
    url: "source.json"
});

if (typeof myCollection === 'undefined') {
    var myCollection = new theCollection; // Only allow it to be created once
}

Ответы [ 6 ]

16 голосов
/ 12 декабря 2011

В вашем случае я бы реализовал своего рода менеджер коллекций:

var manager = (function(){

  var constructors = {
    'example': ExampleCollection
  };
  var collections = {};

  return {
    getCollection: function(name) {
      if(!collections[name]) {
        var collection = new constructors[name]();
        collection.fetch();
        collections[name] = collection;
      }
      return collections[name];
    }
  }
})();

Здесь менеджер отвечает за создание экземпляров коллекций и их выборку.Когда вы звоните:

var exampleCollection = manager.getCollection('example');

, вы получаете экземпляр коллекции примеров с уже загруженными данными.Всякий раз, когда вам понадобится эта коллекция снова, вы можете вызвать метод снова.Затем вы получите точно такой же экземпляр без необходимости извлекать его снова.

Это просто очень простой пример менеджера, и есть множество дополнительных функций, которые вы можете реализовать и улучшить.

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

В CouchApp, над которым я сейчас работаю, я также счел необходимым предотвратить дублирование экземпляров модели в разных коллекциях (разные представления БД могут возвращать одни и те же данные модели).Это было решено с помощью отдельной коллекции в диспетчере, который отслеживает все модели, уже загруженные в приложение.

И последнее, но не менее важное: вы можете рассмотреть возможность применения метода обновления в своих коллекциях или менеджера, который будетобрабатывать обновление коллекции с сервера.Если вы сделаете это методом fetch, вся ваша коллекция будет сброшена, поэтому все модели будут уничтожены, а затем воссозданы.Это плохо, если у вас есть модели из этой коллекции, на которые есть ссылки в другом месте приложения (как вы это обычно делаете).Эти экземпляры устарели и дублируются в вашем приложении.Метод refresh проверяет, есть ли экземпляры с входящим идентификатором в коллекции curent.Если это так, они обновляются, в противном случае они добавляются.

2 голосов
/ 16 декабря 2011

Если под кешированием вы на самом деле имеете в виду одноэлементный объект, так что вы можете ссылаться на один и тот же список доменов из нескольких мест в модульном приложении JS, мы используем для этого RequireJS .Вы можете отделить свою коллекцию, чтобы она была модулем в приложении, которое вам потребуется везде, где вы ее используете.В псевдокоде:

require(["myCollection"],
    function(myCollection) {
        var MyView = Backbone.View.extend();
        new MyView({
            collection: myCollection
        }).render();
    }
);

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

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

Вы можете попробовать

https://github.com/mrappleton/backbone-fetch-cache

Он также имеет поддержку expires, с помощью которой легко установить максимальное время кеша.

0 голосов
/ 31 марта 2012

Я закончил тем, что делал что-то похожее на решение ProTom.Вместо того, чтобы динамически инициализировать коллекцию на основе имени, я решил просто использовать функцию для настройки коллекции.Через мое приложение мне нужно было по-разному инициализировать коллекции в зависимости от того, откуда они поступают.Это оказалось лучшим способом для моих нужд.Вот код CoffeeScript:

Кэш:

cachedCollections: {}
getCollection: (key, block) ->
  collection = @cachedCollections[key]
  return collection if collection
  collection = block()
  @cachedCollections[key] = collection
  collection

Использование:

commentCollection = getCollection "comments-#{postId}", ->
  collection = new CommentCollection
  collection.url = "/api/posts/#{postId}/comments"
  collection
0 голосов
/ 18 декабря 2011

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

Просто загрузите коллекцию, когда страница загрузится

$(function() {
  myCollection = theCollection();
  myCollection.fetch();
});

Поскольку var не используется для объявления myCollection , он становится глобальной переменной.

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

0 голосов
/ 12 декабря 2011

Вы можете попытаться сохранить свою коллекцию в localStorage. Вот ссылка (http://documentcloud.github.com/backbone/#examples-todos).

Приложение использует адаптер LocalStorage для прозрачного сохранения всех ваших задач в браузере вместо их отправки на сервер.

Надеюсь, это поможет:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...