2015-05-13 3 views
2

Я не понимаю, как модели ember загружают связанные модели.Ember.js: Загрузка похожих моделей напрямую

Допустит, то будет моя модель:

export default DS.Model.extend({ 
    title: DS.attr('string'), 
    description: DS.attr('string'), 
    states: DS.hasMany('state', {async: true}) 
}) 

загружает это на моих внешних маршруты. При навигации с помощью ember-app (во вложенные маршруты) часто используются контексты модели для маршрутов, а не с помощью крючка модели маршрута, но с помощью ссылки-помощника (при использовании динамических сегментов модель-крючок будет игнорируются). Когда у целевого маршрута есть что-то в своем шаблоне, например {{#each model.states as |state|}}, ember автоматически загрузит соответствующие модели-записи из (в этом случае) модели состояния. (Как и почему?) Из-за each в шаблоне

При непосредственном доступе к динамическому маршруту модель не предоставляется, и модельный крюк динамического маршрута будет вызываться. Поэтому загрузка моей модели легко: просто переопределите привязку модели и загрузите запись с параметром url (return this.store.find('item', {title: params.item_title})). Но никаких связанных моделей не будет загружен. Как я могу это сделать вручную и что (и когда) - это способ, которым это делает по умолчанию?

ответ

7

Как Ember знает, как автоматически получать отношения?

Данные ember позволяют определять отношения (в настоящее время только belongsTo и hasMany) с опцией async, установленной на true или false. Исходя из этого параметра, после извлечения модели из API (с помощью метода find), данные ember будут ожидать, что объекты отношений будут либо непосредственно в ответном JSON, либо нет. У вас есть async: true (что является довольно распространенным и поддерживаемым способом обработки отношений), поэтому данные ember-данных предполагают, что в вашем ответе JSON он получает id s состояний, но не обязательно сами состояния.

Если вы определяете свой hasMany как async: true, то всегда возвращает обещание. Это означает, что если вы сделаете что-то вроде этого:

this.get("item").get("states")[0] 

не будет работать, так как get("states") не будет возвращать массив, но обещание для извлечения этого массива. Однако Handlebars являются интеллектуальными (как методы get и set Ember), и он может узнать, что является обещанием, и дождаться его разрешения до его использования. Поэтому, если ваш шаблон содержит:

{{#each model.states as |state|}} 

Рули узнает, что states это обещание, ждать его, чтобы решить, и после того, как решительно они используют его содержимое в виде массива. Очень похожее поведение можно найти с помощью метода belongsTo. Предполагая, что ваш item имеет один state, если вы используете код следующим образом:

this.get("item.state.somePropertyOfState") 

Даже если вы не принесли state и в настоящее время вы не знаете, что это значение somePropertyOfState, уголек get выяснит это обещание и получить его для вас автоматически.

Как я могу вручную установить отношения?

Существует несколько способов сделать это.

Первый из них явно за ними в Ember код:

this.get("item.states").then(function(states) { 
    # now you have fetched the states that the item has, and moreover 
    # they are accessible in states variable 
}); 

Во-вторых, вы можете позволить Ember сделать это автоматически для вас, как я описал ранее (например, с помощью шаблона).

В-третьих, вы можете отправить отношения с ответом, используя механизм под названием sideload. Это значительно сократит количество запросов API. Когда вы разрешаете ember извлекать ваши отношения, ember выполняет один запрос на один объект отношения, а это означает, что если у вас есть десять states, принадлежащих item, API будет удален десять раз. Однако, если вы отключите states, извлекая item, запрос будет отправлен только один раз. Take a look here, чтобы получить дополнительную информацию об этом.

Извините за длинный пост, но я надеюсь, что немного осветил.

+0

Хорошо, спасибо вам большое! Очень полезно. Но вы говорите, что ember загружается автоматически, если какое-то значение будет использовано в шаблоне. Ну, в моем приложении это не так! - Загруженный модель - Link-к вложенному маршруту - используя что-то вроде {{model.relatedrecords.title}} в этом шаблоне - ничего СЛУЧИЛАСЬ (даже не запрос отдыха) (позволяет сказать, мою первую загруженную модель получил член, например, связанные с ним записи {hasmany для другой модели}) –

+1

Измените .than -> .then –

+0

Используя первый способ, как вы могли затем перебирать состояния? – Oli

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