Можно ли инициализировать базовую коллекцию идентификаторами объектов, а не объектами?

У меня есть костяк.JS Collection и у меня есть массив идентификаторов моделей,которые я хочу заполнить. Я знаю, что могу получить эти объекты один за другим, построить массив объектов и передать их в конструктор коллекции в виде массива.

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

выполнимо?

3 ответов


когда вы вызываете "fetch" на позвоночнике.Коллекция, она в свою очередь называет магистралью.синхронизация, которая по умолчанию просто запрашивает коллекцию для использования url-адреса.

Так что если ваш сервер отвечает:

/models/batch/?ids=1,2,3,4

вы могли бы сделать что-то вроде:

var MyCollection = Backbone.Collection.extend({

    model: Model,

    url: '/models',

    initialize: function(models, options) {
        ids = options.ids || [];
        if (ids.length > 0) { 
            this.fetchByIds(ids);
        }
    },

    fetchByIds: function(ids) {
        // Save a reference to the existing url
        var baseUrl = this.url;

        // Assign our batch url to the 'url' property and call the server
        this.url += '/?ids=' + ids.join(',');
        this.fetch();

        // Restore the 'url' property
        this.url = baseUrl;
    }
});

и использовать его вот так:

var coll = new MyCollection({}, {ids: [1, 2, 3, 4]});

вам придется передать идентификаторы в параметре options, потому что магистраль.Функция конструктора коллекции задает модели, переданные в первом параметре перед вызовом функция "инициализировать".

теоретически это должно работать (читать: полностью непроверенный).


при начальной загрузке страницы вы не должны использовать fetch -- он должен быть загружен как using reset описано здесь: http://documentcloud.github.com/backbone/#FAQ-bootstrap.

из ссылки:

Загрузка Загрузочных Моделей

когда ваше приложение загружается впервые, обычно есть набор начальных моделей, которые, как вы знаете, вам понадобятся, чтобы отобразить страницу. Вместо того, чтобы запускать дополнительный запрос AJAX для их получения, a более приятным шаблоном является то, что их данные уже загружены на страницу. Затем можно использовать reset для заполнения коллекций исходными данными. В DocumentCloud, в шаблоне ERB для рабочей области, мы делаем что-то в этом роде:

<script>
  Accounts.reset(<%= @accounts.to_json %>);
  Projects.reset(<%= @projects.to_json(:collaborators => true) %>);
</script>

вы также можете установить url-адрес для функции. Я бы просто переопределил fetch вместо fetchByIds: Кроме того, я думаю, что baseUrl предназначен только для модели, а не для коллекции. Я думаю, что у rulfzid есть правильная идея, но я думаю, что я бы сделал это так:

var MyCollection = Backbone.Collection.extend({
  model: Model,

  initialize: function(models, opts) {
    if (options.ids) {
      this.fetch(options.ids);
    }  
  },

  url: function() {
    var url = '';
    if (this.fetch_ids) {
      // pass ids as you would a multi-select so the server will parse them into
      // a list for you.  if it's rails you'd do: id[]=
      url = '/models?id=' + ids.join('&id=');
      // clear out send_ids
      this.fetch_ids = undefined;
    } else {
      url = '/models';
    }
    return url;
  },

  fetch: function(args) {
    if (args.ids) {
      this.fetch_ids = args.ids;
    }
    return Backbone.Model.prototype.fetch.call(this, args);
  }
});

Я думаю, что он сохраняет функциональность в правильном "месте", и это позволяет больше повторно использовать (т. е. вы можете получить(list_of_ids) в любое время... вам не нужен новый объект)