Fetch

У меня есть две базовые модели, загруженные с сервера:

var Model = Backbone.Model.extend({});
var SubModel = Backbone.Model.extend({});

var SubCollection = Backbone.Collection.extend({
    model: SubModel
});

var m = new Model();
m.fetch({success: function(model)
{
    model.submodels = new SubCollection();
    model.submodels.url = "/sub/" + model.get("id");
    model.submodels.fetch();
}});

Итак, сервер должен отправить два отдельных ответа. Например:

{ name: "Model1", id: 1 } // For Model fetch

и

[{ name: "Submodel1", id: 1 }, { name: "Submodel2", id: 2 }] // For Submodel collection fetch

Есть ли способ получить экземпляр модели с коллекцией Submodel сразу, например:

{ 
  name: "Model1", 
  id: 1, 
  submodels: [{ name: "Submodel1", id: 2 }, { name: "Submodel1", id: 2 }]
}

Ответ 1

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

Можете ли вы настроить встроенную технологию для возврата связанных моделей в виде вложенных ресурсов?

Если ваш back-end - Rails, например, и ваши модели связаны с ActiveRecord, один из способов сделать это - это что-то вроде

respond_to do |format|
  format.json  { render :json => @model.to_json(:include => [:submodels])}
end

Какую внутреннюю технологию вы используете?

Edit:

Извините, непонятый смысл вашего вопроса, как только вы вернетесь обратно в JSON в правильном формате, да, есть вещи, которые вам нужно сделать в Backbone, чтобы иметь возможность справиться с этим.

Магистраль-реляционная

Один из способов борьбы с ним - использовать Backbone-Relational плагин для обработки связанных моделей.

Вы определяете связанные модели с помощью свойства отношений:

SubModel = Backbone.RelationalModel.extend({});

SubCollection = Backbone.Collection.extend({
    model: SubModel
});

Model = Backbone.RelationalModel.extend({
  relations: [
    {
        type: 'HasMany',
        key: 'submodels',
        relatedModel: 'SubModel',
        collectionType: 'SubCollection'
    }
  ]
});

Когда ваша модель извлекает JSON, она автоматически создаст SubCollection в соответствии с свойством "subodels" и заполнит его SubModels - по одному для каждого объекта JSON в массиве.

jsfiddle для базового реляционного: http://jsfiddle.net/4Zx5X/12/

Рукой

Вы можете сделать это вручную, если хотите. In включает в себя переопределение функции parse для вашего класса модели (простите меня, если мой JS не на 100% правилен) делал CoffeeScript так много в последнее время его жестко связанный в моем мозгу)

var Model = Backbone.Model.extend({
  parse: function(response) {
    this.submodels = new SubCollection();
    // Populate your submodels with the data from the response.
    // Could also use .add() if you wanted events for each one.
    this.submodels.reset(response.submodels);
    // now that we've handled that data, delete it
    delete response.submodels;
    // return the rest of the data to be handled by Backbone normally.
    return response;
  }
});

parse() запускается до initialize() и до того, как хеш атрибутов настроен, поэтому вы не можете получить доступ к параметрам model.attributes, а model.set() не удается, поэтому мы должны установить коллекцию как прямое свойство модель, а не как "свойство", с которым вы бы получили доступ с помощью get/set.

В зависимости от того, что вы хотите совершить на "save()", вам может потребоваться переопределить `toJSON ', чтобы ваша сериализованная версия модели выглядела так, как ожидал ваш API.

jsfiddle:

http://jsfiddle.net/QEdmB/44/