Как создать коллекцию с несколькими типами моделей в backbone.js? - PullRequest
7 голосов
/ 22 августа 2011

Я пытаюсь заставить это работать, но я борюсь с этим.Моя коллекция заканчивается пустым, когда я проверяю обратный вызов success на fetch.Это не дает мне никаких явных ошибок во время parse.Вот мой код:

Моя коллекция:

VOR.Collections.GridItems = Backbone.Collection.extend({
        model : VOR.Models.GridItem,
        url: "assets/data/grid.json",
        parse: function(response){
            var self = this;

            _.each(response, function(griditem){
                switch(griditem.type){
                    case "news":
                        self.add(new VOR.Models.NewsGridItem(griditem));
                        break;
                    default:
                        self.add(new VOR.Models.StandardGridItem(griditem));
                        break;
                }
            });
        }
});

Вот как я создаю коллекцию:

griditems = new VOR.Collections.GridItems();

griditems.fetch({
    error: function(e) {console.log(e);},
    success: function(msg) {
        console.log(msg)
    });

Когда я консольный журнал msg, я получаю: Object{length = 0, models = [0], _byId = {...}, еще ...}

Я также зарегистрировал функцию parse в коллекции, и она запускается через файл JSONпросто отлично ... есть идеи о том, что здесь может быть не так?Длина объекта msg должна составлять 5..ie, то есть сколько раз циклы функции parse и (должны) добавлять модель в коллекцию.

Ответы [ 3 ]

18 голосов
/ 23 августа 2011

Хороший способ справиться с этим - переопределить атрибут model, который сообщает коллекции, как добавить новую модель в коллекцию, как описано в этом POST: Коллекция Backbone.js нескольких подклассов Model. (спасибо @rulfzid, который ответил на мой вопрос:))

В вашем случае вы сможете определить атрибуты модели следующим образом:

var VOR.Collections.GridItems = Backbone.Collection.extend({

  url: "assets/data/grid.json",

  model: function(attrs, options) {
    switch(attrs.type) {
      case "news":
        return new VOR.Models.NewsGridItem(attrs, options);
      default:
        return new VOR.Models.StandardGridItem(attrs, options);
    }
  }

});
1 голос
/ 23 августа 2011

Будет лучше хранить ваши элементы сетки в разных коллекциях и обернуть их моделью следующим образом:

var model = Backbone.Model.extend({
    url: 'assets/data/grid.json'
    newsItems: Backbone.Collection.extend({
        model: VOR.Models.NewsGridItem
    }),
    standartItems: Backbone.Collection.extend({
        model: VOR.Models.StandardGridItem
    }),

    initialize: function() {
        this.newsItems = new this.newsItems();
        this.standartItems = new this.standartItems();

        this.newsItems.bind('all', function() {
            this.trigger.apply(this, arguments);
        }, this)
        this.standartItems.bind('all', function() {
            this.trigger.apply(this, arguments);
        }, this)
    },

    parse: function(request) {
        _.each(response, _.bind(function(griditem) {
            switch (griditem.type) {
                case "news":
                    this.newsItems.add(griditem);
                    break;
                default:
                    this.standartItems.add(griditem);
                    break;
            }
        }, this));
    }
})

model.fetch()
0 голосов
/ 22 августа 2011
// **parse** converts a response into a list of models to be added to the
// collection. The default implementation is just to pass it through.
parse : function(resp) {
  return resp;
},

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

  options.success = function(resp) {
    collection[options.add ? 'add' : 'refresh'](collection.parse(resp), options);
    if (success) success(collection, resp);
  }

Поэтому я бы предложил изменить ваш синтаксический анализ на:

return _.map(response, function(griditem){
    switch(griditem.type){
        case "news":
            return new VOR.Models.NewsGridItem(griditem);
            break;
        default:
            return new VOR.Models.StandardGridItem(griditem);
            break;
    }
});
...