0

Backbone 1.1.2
Подчеркивания 1.7.0
JQuery 1.11.1Различных типов моделей в одной коллекции Backbone

У меня есть один сборник, который содержит сообщение. Мои сообщения могут быть разных типов (и конечные точки в api различны для каждого типа, но у меня есть конечная точка, которая позволяет мне делать один запрос и получать все сообщения)

Когда Collection.fetch() Мне нужно определить, какую модель использовать при заполнении коллекции на основе существующих свойств.

Я попытался, как предложено здесь: A Backbone.js Collection of multiple Model subclasses , а также основой документации backbonejs.org

Мой код выглядит следующим образом

model: function (attr, options) { 
    if(attr.hasOwnProperty('prop')){ 
     return new PropModel(attr,options); 
    } 
    else if(attr.hasOwnProperty('another_prop')){ 
     new AnotherPropModel(attr,options); 
    } 
}, 

СТОИМОСТИ атр только один большой массив объектов, так что без прохождения почему-то это решение не имеет для меня никакого смысла и его очевидного, почему это не работает.

Я правильно справляюсь с этим, есть ли другой способ сделать это?

--- UPDATE ----

Я также попытался сделать это в функции Разбор коллекции и моя коллекция просто пустой

parse: function (resp, options) { 
    _.each(resp, _.bind(function (r) { 
     console.log(this); 
     if(r.hasOwnProperty('prop')){ 
      this.add(new PropModel(r)); 
     }else{ 
      this.add(new AnotherPropModel(r)); 
     } 
    },this)); 
} 
+0

Есть ли ключ почтительность в период между моделями? Или это просто URL? – anAgent

+0

@anAgent Атрибуты для каждого из них разные, поэтому я хотел бы отображать модель на модель при рендеринге моего шаблона. Я думаю, что я мог бы сделать эту же логику в шаблоне, но я предпочитаю оставить логику из шаблона, чтобы я мог легко переключаться с шаблонами шаблонов, если это необходимо. – Beyerz

+0

Также URL-адрес важен для меня, так как атрибуты разные. Несмотря на то, что сообщения могут быть сгруппированы, они также независимы в других областях моей системы. – Beyerz

ответ

0

Таким образом, решение было сочетанием использования функции модели и возврата.

Здесь идет объяснение:

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

parse: function (resp, options) { 
    return resp; 
} 

В моем случае, сервер возвращал объект объекта как

{{1:data},{2:data}} 

Во-первых, это странно и, очевидно, необходимо разрешить. ВАЖНАЯ ТОЧКА: Когда базовая группа оценивает ответную реакцию ответа от разбора, ему необходимо решить, где остановиться для каждой модели, как в том, что определяет новую модель.

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

Так что я просто изменил свой ответ в функции синтаксического анализа и Voila! все в модельной функции работали, как и ожидалось:

Вот код:

model: function (attr, options) { 
    if(attr.hasOwnProperty('prop')){ 
     return new PropModel(attr,options); 
    } 
    else if (attr.hasOwnProperty('anotherProp')){ 
     return new AnotherPropModel(attr,options); 
    } 
}, 

parse: function (resp, options) { 
    var response = []; 
    _.each(resp, _.bind(function (r) { 
     response.push(r); 
    },this)); 
    return response; 
} 

Я уверен, что есть лучший способ решить объект в массив, но сейчас это работает, и я снова улыбается! !

Эта статья приведет меня к решению: A collection of muppets

+0

Просто комментарий, который вам не нужно использовать _.bind, поскольку третий аргумент _.each является контекстом. Во-вторых, вы не вызываете ничего из области _.each, поэтому это не нужно. – anAgent

+0

Вы правы! Я удалил _.bind, я думаю, я просто привык потерять свой охват, поэтому я склонен связывать функции обратного вызова как привычку. – Beyerz

0

Вы могли бы сделать что-то вроде следующего - реагируя на различный тип (если возможно), а затем укажите другой URL-адрес. Тогда, как только модели JSON в шаблоне, то вы можете сделать HTML, как вам нравится:

Пример JSon

"[{"id":1,"Type":"Person"},{"id":2,"Type":"Business"}]" 

Пример Модель

var Person = Backbone.Model.extend({ 

    keyTypes: { 
     Person: 'Person', 
     Business: 'Business' 
    }, 

    url: function() { 
     // we are assuming only two types. Change logic if there are three or more types. 
     return this.get('Type') === this.keyTypes.Person ? '/api/people' : '/api/businesss'; 
    } 

}); 

Коллекция

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

Просмотр

var View = Backbone.View.extend({ 

    initialize: function() { 
     this.collection = new Collection() 
      .on('fetch', this.render, this); 
    }, 

    bootstrap: function() { 
     this.collection.fetch(); 
    } 

    render: function() { 
     this.$el.html(_.template({ 
      models: this.collection.toJSON() 
     })); 
    } 
}) 

** !! Обновить !! **

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

parse: function (data, options) { 

    var models = []; 
    _.each(data, function (entity) { 
     // this is IE8 Safe.... 
     var model = Object.prototype.hasOwnProperty.call(entity,'prop') ? PropModel : AnotherPropModel; 
     models.push(new model(entity));  
    }); 

    return models; 
} 
+0

Я вижу, как это разрешило бы множественные конечные точки url, но я все еще не понимаю, как это определяет модели для меня, чтобы я мог придумать? – Beyerz

+0

Это ответ на задание для кастинга типа, поэтому я согласен с тем, что он не удовлетворяет вашему точному вопросу. Я думаю, что если вы начнете кастинг типа, вы начнете сталкиваться с другими долгосрочными проблемами, и вам будет сложнее протестировать. – anAgent

+0

Im фактически является фанатом приведения типов, поскольку это заставляет понимать и позволяет быстро выйти из строя. Ваше обновление имеет смысл, я забыл упомянуть, что я работаю над расширением chrome ... поэтому не слишком беспокоился в настоящий момент о совместимости с браузером. – Beyerz

Смежные вопросы