2015-02-14 11 views
1

Я просто наткнулся на Полиморфные отношения Ember Data. Я думаю, что они будут полезны для того, над чем я работаю. Вот моя основная модель. Эта модель определяет, что существует много отношений с темами, которые являются как асинхронными, так и полиморфными.Ember Data - Полиморфные отношения

App.Source = DS.Model.extend({ 
    name: DS.attr('string'), 
    type: DS.attr('string'), 
    locationType: DS.attr('string'), 
    locationSpecific: DS.attr('boolean'), 
    primary: DS.attr('boolean'), 
    published: DS.attr('boolean'), 
    sort: DS.attr('number'), 
    topics: DS.hasMany('topic', { 
     async: true, 
     polymorphic: true 
    }) 
}); 

Далее мы имеем Темы с базовым классом является «Тема»

App.Topic = DS.Model.extend({ 
    name: DS.attr('string'), 
    sort: DS.attr('number'), 
    source: DS.belongsTo('source') 
}); 

App.RegTopic = App.Topic.extend({ 
    test: DS.attr('number', { 
     defaultValue: 8 
    }), 
    notes: DS.hasMany('notes', { 
     async: true 
    }) 
}); 

App.SummaryTopic = App.Topic.extend({ 
    number: DS.attr('number', { 
     defaultValue: 9 
    }) 
}); 

и вот как я называю, чтобы получить темы

App.TopicsRoute = Ember.Route.extend({ 
    model: function() { 
      return this.modelFor('source').get('topics'); 
    } 
}); 

Когда я список источников, Я получаю список следующих объектов назад

{ 
     id: 1 
     name: "test" 
     type: "testType" 
     locationType: "international" 
     locationSpecific: "true" 
     primary: true 
     published: true 
     sort: 1 
     links: { 
       topics: "/topics?sourceId=1" 
     } 
    } 

то моя тема вызов получает объекты, как их обратно

{ 
    id: 4 
    sourceId: 1 
    name: Topic 4 
    type: "regTopic" 
    sort: 1 
} 

ли я что-то отсутствует? Можете ли вы не использовать полиморфные отношения с объектом 'links'?

Из моего понимания Полиморфных отношений, когда я делаю вызов/темы? SourceId = 1, он должен по существу загружать 2 разных темы в один вызов, чтобы затем я мог отображать regTopic и summaryTopic на той же странице, но в отдельные списки и сохранить их как отдельные объекты?

Вот обновленный jsbin, который кажется близким к работе. http://emberjs.jsbin.com/medojitibo/1/edit?html,js,console,output

Проблема, я вижу, что в моем контроллере темы все App.Topic в списке. Нет App.RegTopic или App.SummaryTopic

+0

1. В чем же проблема? 2. Просьба представить демонстрационную версию проблемы через http://emberjs.jsbin.com/ –

ответ

0

Элемент links выглядит как JSON-API, для которого есть addon. Мне пришлось внести изменения в полиморфизм в моем fork. Возможно, вам будет проще модифицировать ваш сервер, чтобы поддерживать API, указанный Ember Data.

+0

Ну, элемент ссылок работает с RestAdapter. Он вызывает вызов, чтобы получить темы, но после этого он никогда не превращает список тем в конкретные темы (RegTopic & SummaryTopic). Также если Im не ошибается, вы только фиксировали ссылки полиморфные отношения для ownTo, а не hasMany? – bakerac4

0

Я бы не рекомендовал использовать полиморфизм Ember Data, если вы действительно не знаете, что делаете, и убедились, что он делает то, что вам нужно. В настоящее время он разработан для довольно ограниченных случаев использования. Существует ряд обсуждений и предложений по теме, которые вы можете отслеживать, если вы заинтересованы.

Вы, видимо, считаете, или считает, что API, что формат для links свойства в формате JSON для source объекта является объектом, содержащий один (?) topics свойства, которое дает API конечной точку для получения полиморфной темы. Это совсем не так.

Правильный синтаксис для links свойства в возвращенном JSON будет массив {id, type} tuplets:

{ 
    id: 1 
    name: "test" 
    type: "testType" 
    ... 
    links: [ 
     { id: 'topic1', type: 'regTopic'}, 
     { id: 'topic2', type: 'summaryTopic' } 
    ] 
} 

Формат данных для ассоциации, как показано выше, представляет собой массив идентификаторов/типа объектов, а не только массив идентификаторов. Это необходимо для полиморфизма данных Ember Data. Если вы не можете организовать для своего исходного кода такой формат, вы в конечном итоге исправите и взломаете ряд методов в адаптерах и сериализаторах, а в конце дня создайте свою собственную версию полиморфизма, возможно, не который вы хотите предпринять.

Без этой специальной формы JSON для свойств ассоциации Ember Data не имеет представления о том, какой тип объекта искать. С его помощью Ember Data создаст подходящий тип экземпляра topic для каждой записи в этом массиве topics и по существу вызовет find('reg-topic', 'topic1') и find('summary-topic', 'topic2'), чтобы получить его данные. Это означает, что для каждого подтипа темы вам также понадобится отдельная конечная точка API. (Вопросы различаются, если темы встроены, альтернатива я не буду вдаваться здесь.)

До сих пор так хорошо, может быть. Но это начинает быстро разрушаться, как только вы начинаете делать более сложные вещи. Предположим, вы хотите получить/получить тему с определенным идентификатором. Можно подумать, что, поскольку «темы являются полиморфными», вы можете просто сделать this.store.get('topic', id). Но вы не можете. Магазин держит RegTopic s и SummaryTopic s в разных местах и ​​не связывает их с Topic. Если вы попросите «Тема», он не знает, что искать под разными (суб) моделями для экземпляров уже в магазине. Поэтому вам нужно заранее знать, что такое тип, и попросить магазин записать этот конкретный тип, который портит всю цель полиморфизма. Если вы просто назовете конечную точку topics, Ember Data создаст новый экземпляр модели для Topic - она ​​не подозревает, что она должна исследовать поле type возвращаемого JSON, чтобы управлять тем, какой подтип его включить.

Дело в том, что здесь темы не полиморфные. В Ember Data полиморфизм не находится на уровне ; он находится на уровне . Другими словами, что является полиморфным, это не сама модель topic; это ассоциации, проведенные в собственности links на модели source. Другими словами, Ember Data не имеет представления о том, что сама модель является полиморфной; он просто знает, что конкретная ассоциация (hasMany или belongsTo) может содержать полиморфные значения. Для некоторого понимания того, что может потребоваться, чтобы Ember Data действительно поддерживала полиморфные модели, хотя и в немного другом контексте, взгляните на https://github.com/Bestra/ember-data-sti-guide.

Чтобы ответить на ваш вопрос в вашем комментарии, нет, полиморфизм Ember Data не лучший способ сделать то, что вы хотите. Не отправляйтесь в эти неизведанные воды. Я бы принял стратегию «полиморфизма бедных людей», где ваша модель Topic имеет поле типа и может иметь или может иметь несколько разных свойств в зависимости от типа. Затем вы можете сортировать, группировать и фильтровать по типу в своем сердце.

+0

Привет torazaburo, спасибо за ответ! Все это произошло потому, что я хочу иметь приложение, имеющее список источников, и эти источники могут иметь три разных типа тем (в некоторых из них только два, у некоторых - все три). В зависимости от источника, когда вы нажимаете ссылку, чтобы перейти к тем тем источников, я хочу отображать все темы, которые есть в списке, разделенные типом темы. Поэтому давайте предположим, что в Source 1 есть только два типа темы: рег и сводные темы. Но источник 1 имеет 3 Reg и 4 сводные темы. Какой был бы лучший способ сделать это? Является ли ember полиморфизм решением для этого? – bakerac4

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