Релиз EMBER DATA 1.13


Мы рады объявить о выходе библиотеки Ember Data 1.13. Спустя три года после ее создания это первый стабильный релиз.

Мы объясняли в посте Проект Ember 2.x, что впредь релизы и номера версий Ember Data будут соответствовать релизам Ember.js.

Ember Data 1.13 — первая версия, которая соответствует версии Ember.js. За ней последует Ember Data 2.0, которую выпустят параллельно с Ember.js 2.0. Ember Data 1.13 — обратно совместима с Ember Data beta .19, что позволяет беспрепятственно обновляться.

Обзор EMBER DATA 1.13

Ember Data 1.13 — масштабный релиз, и мы им гордимся. Главная особенность этой версии — полная реорганизация внутреннего формата Ember Data и Serializer API, который стал преемником JSON API.

Два года назад Том Дейл и Йегуда Кац опубликовали свои мысли о том, как Ember Data будет выглядеть в будущем. Они четко выразили необходимость единого повсеместного стандарта JSON API.

Мы счастливы, что их слова стали реальностью. Стандарт JSON API предстал в форме JSON API 1.0.

C того момента JSON API и Ember.js сплелись воедино. @dgeb рассказывает о происхождении JSON API в своем анонсе версии 1.0:

Йегуда Кац сделал первый набросок спецификации JSON API в мае 2013 года. Перед этим он долго обсуждал детали со Стивом Клабником на конференции RailsConf, пока они не достигли соглашения. Сначала JSON API представлял собой стандартизацию в виде единой серверной библиотеки для Rails, ActiveModel::Serializers и одной клиентской библиотеки JavaScript, Ember Data.

Долгое время Ember Data поддерживал JSON API через социальный репозиторий, который основал @0x8890 и поддерживал @kurko. Но теперь JSON API добрался до версии 1.0. Поэтому Ember Data пришло время исполнить свою часть сделки и превратить JSON API в первоклассный инструмент.

Именно это мы и сделали. В Ember Data 1.13 добавили поддержку JSON API через стек Ember Data:

  • Ember Data 1.13 полностью поддерживает адаптер и сериализатор JSON API. В версии 2.0 они по умолчанию будут адаптером и сериализатором.
  • JSONSerializer и RESTSerializer реорганизовали и модернизировали, чтобы вернуть полезную нагрузку JSON API.
  • store.push теперь принимает соответствующую полезную нагрузку JSON API.
  • Объекты Ember Data InvalidError теперь принимают объекты-ошибки JSON API.

Переключение на формат JSON API раскрывает много новых возможностей, которые добавят в цикл 2.0, включая первоклассную разбивку, фильтрование и поддержку метаданных.

Пока JSONSerializer, RESTSerializer и ActiveModelSerializer не устарели, мы рассматриваем JSON API как наилучший способ для использования Ember Data. Если вы создаете новое приложение и хотите контролировать его через API, то вам следует использовать JSON API. Это отлично спроектированное и всестороннее решение для сериализации JSON. Если ваше приложение использует классический JSONSerializer или RESTSerializer, то вам не нужно ничего менять, а приложение продолжит работать. Существующие сериализаторы обновляются в режиме обратной совместимости, чтобы вернуть данные JSON API в хранилище.

Другие изменения в Ember Data 1.13:

Руководство по обновлению

Ember Data 1.13 поддерживает обратную совместимость с предыдущими бета-версиями. Между Ember Data 1.13 и Ember Data beta.19 нет критических изменений. В этом релизе Ember Data следует за Ember.js, поэтому функциональность не тронута. Процедура обновления должна быть знакома пользователям Ember.js: обновиться, удалить устаревшие элементы, обновиться снова.

Вам следует обновить кодовую базу до Ember Data 1.13, удалить все устаревшие элементы и затем перейти на Ember Data 2.0. Очень важно выполнять процедуру поэтапно. Так вам будет проще следовать оповещениям об устаревших элементах. Иначе приложение может некорректно себя повести в процессе отладки.

Если вы настроили сериализатор под себя, то следует обновиться до Ember Data 1.13 и проверить руководство по обновлению, чтобы понять, нужны ли еще какие-либо изменения. Затем необходимо установить временный флажок на вашем сериализаторе: isNewSerializerAPI. Таким образом, вы останавливаете свой выбор в пользу нового API сериализатора. Когда вы обновитесь до Ember Data 2.0, новый API сериализатора будет стоять изначально, и флажок не понадобится.

Мы опубликуем подробные инструкции обновления вместе с руководством по устаревшим средствам Ember.js и помощникам ember-watson. Они автоматически обновят для вас некоторые устаревшие элементы.

Управление релизами

Ember Data 1.13 — последний релиз Ember Data, который поддерживает IE8 и серию Ember.js 1.x. Ember Data 2.0-beta.1 выйдет в ближайшее время и будет соответствовать релизу Ember.js. Ember Data 2.0 не будет работать с серией Ember.js 1.x.

Мы выражаем отдельную благодарность разработчикам, которые приложили немало усилий к созданию этого релиза. И мы благодарим всех, кто помогал решать проблемы во время подготовки релиза. Если вы хотите поучаствовать в разработке, присоединяйтесь к #dev-ember-data в сообществе Ember Community на Slack.

Мы также хотим поблагодарить компании, которые проспонсировали часть работы над Ember Data:

Как всегда, релиз доступен через npm (для использования с ember-cli), rubygems или bower. Также сборки можно найти в виде статических файлов по ссылке http://emberjs.com/builds.

Новые особенности

Упрощенные методы поиска

Методы Ember Data для работы с хранилищем данных развивались на протяжении всего жизненного цикла проекта. Изначально, в Ember Data использовался store.find(type), чтобы запросить все записи определенного типа, и store.find(type, id) — для запроса конкретной записи. Затем в Ember Data добавили способы создавать запрос серверу с помощью store.find(type, {query}) или всегда повторно загружать записи backend через store.fetchById(type, id) и store.fetchAll(type).

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

В частности, store.find, store.all, store.getById устарели, и их заменили на методы с единообразными наименованиями. Новые методы следуют простым правилам: если они асинхронные и потенциально обращаются к серверу, то начинаются с find, а если они получают только локальные данные без побочных эффектов, то начинаются с peek. Если они возвращают только одну запись, то оканчиваются на Record, а если возвращают все записи — то на All.

Реорганизованные методы поиска

Асинхронный с сервера/хранилищаСинхронный с хранилищаСервер запросов
Одна записьfindRecord(type,id)peekRecord(type, id)queryRecord(type, {query})
Все записиfindAll(type)peekAll(type)query(type, {query})*

* Запрос обычно не возвращает все записи определенного типа, поэтому не заканчивается на All.

Методы QUERY И QUERYRECORD

Последний случай, где применяли старый метод store.find — отправка запросов на сервер. Метод store.find(type, { query }) устарел, и его заменили на новый метод query.

store.query(type, { query });

В дополнение к store.query мы также добавили queryRecord для отправки произвольных запросов на backend, где ожидаемый ответ — это единичная запись.

store.queryRecord(type, { query });

Благодарим @thaume за его работу над реализацией этой особенности.

Улучшенные изначальные параметры кэширования для методов findAll и findRecord

В Ember Data beta.19 вызов store.find(type, id) сначала вернул с сервера свежие данные, а затем каждый последующий раз возвращал бы кэшированные данные. Если пользователю постоянно были нужны свежие данные, приходилось вызывать store.fetchRecord. А если требовалось фоновое обновление, то пользователи прибегали к множественным вызовам. И приходилось следить за тем, что они возвращают от hook model: маршрута.

Вызов store.find(type) имел противоположное поведение. Он всегда обращался к серверу, а пользователь должен был применять store.all(type), чтобы использовать только локальные данные. Симуляция поведения кэширования find(type, id) при использовании find(type) была плохо понятна начинающим разработчикам.

Мы проанализировали на практике множество приложений Ember и осознали, что ни одно из этих двух поведений не является распространенным случаем использования и не заслуживает стоять по умолчанию. Лучшее поведение, которое мы увидели в приложениях Ember, заключалось в следующем:

  • store.find возвращает новые данные при первом вызове
  • В следующий раз возвращает кэшированные данные
  • возвращает новые данные в фоновом режиме и обновляется

Именно так ведут себя новые методы findRecord и findAll.

При первом вызове findRecord и findAll они ведут себя так же, как и старый метод find:

//visiting /users/1 for the first time
model: function() {
  //We do not already have the user, so
  //store.findRecord returns a promise that resolves
  //after it has fetched the user from the server
  return this.store.findRecord('user', 1);
}

Но если у вас уже есть кэшированные локальные данные, они сразу же реализуются, пока выборка новых данных происходит в фоновом режиме:

//visiting /users/1 for the second time
model: function() {
  //We already have the user, so store.findRecord
  //will resolve immediately with cached data, but will
  //send off a request in the background to update the user record
  //and once the user is updated your template will show the new changes
  return this.store.findRecord('user', 1);
}

Это отличная стратегия выборки данных, которую следует оставить по умолчанию. Но иногда необходимо убедиться, что у вас свежие данные (поведение старого метода store.fetch), или убрать фоновые обновления (поведение старого метода store.find(type, id)).

Для этого findRecord и findAll принимают reload: true и backgroundReload: false в качестве опций, чтобы подправить их изначальное поведение.

Например, вам нужно списать с пользователя средства за покупки. Вы хотите убедиться, что получаете последние сведения о балансе его счета. Вы можете передать опцию reload: true, которая проверит актуальность данных, прежде чем продолжить:

//visiting /users/1/confirm-payment
model: function() {
  store.findRecord('user', 1, { reload: true });
}

Если вы показываете пользователю модальное окно с настройками и хотите отключить фоновые обновления, чтобы поддерживать стабильность пользовательского интерфейса, то можете передать backgroundReload: false в качестве флажка:

//visiting /users/1/open-modal
model: function() {
  store.findRecord('user', 1, { backgroundReload: false });
}

Такое поведение относится также и к findAll:

store.findAll('user');  //goes to the server the first time
store.findAll('user');  //after that returns from cache, but updates in background
store.findAll('user', { reload: true });  //enforces getting fresh data
store.findAll('user', { backgroundReload: false });  //opts out of background updating

findRecord и findAll заменили fetchById и fetchAll

Наличие двух методов с настраиваемыми флажками позволяет избавиться от store.fetchById и store.fetchAll.

store.fetchById(type, id) -> store.findRecord(type, id, { reload: true });
store.fetchAll(type, id) -> store.findAll(type, { reload: true });

Новые HOOKS адаптера для улучшения кэширования

Хотя store.findRecord и store.findAll теперь имеют целесообразные исходные параметры и легко поддаются переопределению в особых местах приложения, зачастую ваши уровни приложения и адаптера имеют свою информацию о кэшировании. Например, ваш backend выдал заголовок expires, или вы не хотите осуществлять выборку фоновых обновлений при отсутствии сети. Для таких случаев мы добавили новые hooks адаптера, чтобы более тонко настраивать кэширование в приложении с помощью передачи опций findRecord и findAll.

Теперь при вызове findRecord или findAll, когда запись уже сохранена в кэше в хранилище, хранилище отправит адаптеру запрос: нужно ли немедленно перезагрузить запись или обновить ее в фоновом режиме.

Например, вы пишете систему обеспечения билетами, где пользователи могут резервировать билеты только на 20 минут за один раз. Вы хотите убедиться, что в каждом маршруте будут данные не старее 20-ти минут. Для этого сделайте следующее:

shouldReloadRecord: function(store, ticketSnapshot) {
  let timeDiff = moment().diff(ticketSnapshot.attr('lastAccessedAt')).minutes();
  if (timeDiff > 20) {
    return true;    
  } else {
    return false;
  }
}, 

Этот метод позволяет удостовериться, что при вызове findRecord('ticket') вы всегда будете получать данные о билетах не старее 20-ти минут. Если кэшированная версия существует дольше 20-ти минут, findRecord не реализуется, пока вы не получите последней версии данных. По умолчанию этот hook возвращает false, так как большинство интерфейсов не должны блокировать действия пользователя во время ожидания обновления данных.

Также можно настроить фоновое обновление. Например, если вы не хотите извлекать сложные данные через мобильное подключение, или нет сети, то можно выполнить shouldBackgroundReloadRecord.

shouldBackgroundReloadRecord: function(store, snapshot) {
  if (window.navigator.connection === 'cellular' ||
    window.navigator.connection === 'none') {
    return false;
  } else {
    return true;
  }
}

Хранилище данных вызывает Adapter#shouldBackgroundReloadRecord, когда оно разрешает обещание findRecord с кэшированной записью. Если метод возвращает true, хранилище попытается перезагрузить запись из адаптера в фоновом режиме. По умолчанию, в Ember Data 1.13 этот метод всегда возвращает false, чтобы упростить способ обновления. Но в Ember Data 2.0 метод всегда будет возвращать true.

Симметричные методы добавили и для store.findAll.

shouldReloadAll: function(store, snapshotRecordArray)
shouldBackgroundReloadAll: function(store, snapshotRecordArray)

@eccegordo составил следующую таблицу со всеми новыми API и методами хранения, которые они заменяют.

Ember beta.19Ember 1.13
store.getById(type, id)store.peekRecord(type, id)
store.all(type)store.peekAll(type)
store.find(type, id)store.findRecord(type, id, options)
store.find(type)store.findAll(type, options)
N/Astore.queryRecord(type, query)
store.find(type, { query })store.query(type, query)
store.fetch(type, id)store.findRecord(type, id, {reload: true})

ПОДДЕРЖКА JSON API

Адаптер и сериализатор JSON API

Ember Data 1.13 поддерживает JSON API 1.0. Есть новые DS.JSONAPIAdapter и DS.JSONAPISerializer, которые поддерживают работу с backends JSON API. В версии 2.0 Ember Data будет по умолчанию загружать адаптер JSON API.

Изменение внутреннего формата JSON API

В Ember Data beta.19 вы связывали обновления с хранилищем через вызов store.push(type, id). Мы изменили store.push, и теперь он принимает объект JSON API, store.push({JSON API compound document}).

Например:

store.push('user', { id: 1, name: 'Pangratz' });

становится

store.push({
  data: {
    id: '1', 
    type: 'user', 
    attributes: { 
      name: 'Pangratz' 
    }
  }
});

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

Мы вскоре опубликуем информацию о помощнике ember-watson, который переписывает под новый формат все случаи применения store.push внутри ваших средств тестирования. Еще мы расскажем о дополнении с помощниками, которые конвертируют старый формат store.push в новый.

Новый сериализатор API для авторских сериализаторов

Если вы создавали запрос store.findRecord('user', 1) в Ember Data beta.19, и полезная нагрузка сервера выглядела так:

{
  user: { id: 1, name: 'wecc', accounts: [1, 2] },
  accounts: [
    { id: 1, email: 'wecc@sweden.se' },
    { id: 2, email: 'wecc@greece.gr' }
  ]
}

Ваш сериализатор получал полезную нагрузку, переданную в hook extract. Тогда его задачами были:

  • нормализовать и store.push все, что не primary record, в этом случае — массив загруженных аккаунтов
  • нормализовать и вернуть первичные данные, в этом случае — данные user.

Наличие этих двух способов передачи данных в хранилище, с возвратом первичных записей данных из hook extract и выполнением store.push с другими данными, вызывало путаницу, затрудняло отладку, оптимизацию и не позволяло внедрить поддержку нужных метаданных, особенно для загруженных массивов и записей.

В Ember Data 1.13 этот процесс сильно упростили. В версии 1.13 сериализаторы просто согласовывают всю полезную нагрузку со стандартами JSON API и полностью ее возвращают. Им больше не требуется store.push самих себя.

Чтобы обеспечить обратную совместимость, мы создали новый hook normalizeResponse. Сериализаторы теперь его выполняют и возвращают только JSON API из этого hook.

Например, сериализатор, который отвечает за нормализацию вышеуказанного примера полезной нагрузки, просто преобразует ее в следующее:

{
  data: { 
    id: '1', 
    type: 'user', 
    attributes: {
      name: 'wecc'
    }, 
    relationships: {
      accounts: {
        data: [
          { id: '1', type: 'account' },
          { id: '2', type: 'account' }
        ]
      }
    }
  },
  included: [{ 
    id: '1',
    type: 'account',
    attributes: {
      email: 'wecc@sweden.se'
    }
  }, {
    id: '2',
    type: 'account',
    attributes: {
      email: 'wecc@greece.gr'
    }
  }]
}

В скором времени мы разместим подробное руководство по переходу на новый сериализатор.

Новые API JSONSERIALIZER и RESTSERIALIZER

Так как мы переписали JSONSerializer и RESTSerializer для внедрения нового Serializer API, мы также упростили и улучшили их собственные API. Раньше подправить ответ для store.find('user', 1) можно было в следующих местах:

  • extract
  • extractFind
  • extractSingle
  • normalizePayload
  • normalizeHash
  • normalize
  • extractMeta
  • normalizeRelationships
  • normalizeAttributes

Новый Serializer API упростил задачу. Если вы получаете ответ на store.findRecord('user', 1) в Ember Data 1.13, то можете индивидуально настроить свой ответ в:

  • normalizeResponse — метод ввода в сериализаторе, который отвечает за нормализацию любого ответа, получает всю полезную нагрузку, возвращает составной документ JSON API
  • normalizeFindRecordResponse — normalizeResponse для конкретных операций
  • normalize — нормализует данные для одной записи, возвращает составной документ JSON API
    • extractId | extractAttributes | extractRelationships — normalize поручает этим методам извлекать идентификатор, атрибуты и связи из полезной нагрузки. Они получают всю полезную нагрузку для одной записи и возвращают подмножество данных для идентификатора, атрибутов и связей в соответствии со спецификацией JSON API.
  • extractMeta — извлекает метаданные для полезной нагрузки.

Переход на новые API JSONSERIALIZER и RESTSERIALIZER

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

Индивидуальные методы extract

Если у вас есть индивидуальные hooks extract, вам нужно сделать две вещи:

Во-первых, переименовать:

  • extract() => normalizeResponse()
  • extractFindAll() => normalizeFindAllResponse()
  • extractFind() => normalizeFindRecordResponse()
  • extractFindMany() => normalizeFindManyResponse()
  • extractFindBelongsTo() => normalizeFindBelongsToResponse()
  • extractFindHasMany() => normalizeFindHasManyResponse()
  • extractFindQuery() => normalizeQueryResponse()
  • extractQueryRecord() => normalizeQueryRecordResponse()
  • extractCreateRecord() => normalizeCreateRecordResponse()
  • extractDeleteRecord() => normalizeDeleteRecordResponse()
  • extractUpdateRecord() => normalizeUpdateRecordResponse()
  • extractSave() => normalizeSaveResponse()
  • extractSingle() => normalizeSingleResponse()
  • extractArray() => normalizeArrayResponse()

Во-вторых, убедитесь, что ваши hooks extract возвращают полный составной документ JSON API (http://jsonapi.org/format/#document-top-level) со всеми основными ресурсами в массиве или объекте data и возможными загруженными ресурсами в массиве included. Каждый объект ресурса (http://jsonapi.org/format/#document-resource-objects) должен соответствовать формату JSON API по id, type, атрибутам в attributes и связям в relationships. Полные спецификации формата JSON API можно найти здесь http://jsonapi.org/format/.

Индивидуальный метод extractMeta

Если у вас есть индивидуальный метод extractMeta, убедитесь, что он возвращает метаданные, а не вызывает store.setMetadataFor() (или полагается на _super, чтобы сделать это).

Индивидуальный метод normalize

Если у вас есть индивидуальный метод normalize(), вам нужно обновить его, чтобы вернуть полный документ JSON API (http://jsonapi.org/format/#document-top-level) с объектом основного ресурса (http://jsonapi.org/format/#document-resource-objects), который находится в data.

Переход на новый SERIALIZER API

Чтобы указать Ember Data, что вы готовы использовать новый Serializer API, добавьте isNewSerializerAPI: true при расширении JSONSerializer или RESTSerializer. Новый JSONAPISerializerпо умолчанию использует новый Serializer API. Флажок isNewSerializerAPI нужен только для Ember Data 1.13 и будет удален в Ember Data 2.0. Новый JSONAPISerializer поддерживает только новый Serializer API.

Благодарим @wecc за его работу по реализации этой особенности с обратной совместимостью.

Также благодарим @kurko за его поддержку сообщества адаптера JSON API.

Новый API для обработки ошибок

Как и API для поиска, API для обработки ошибок со временем развился, и переход на JSON API дал возможность провести чистку и стандартизацию. @tchak проделал огромную работу, чтобы переписать Errors API для совместимости с JSON API и сохранить при этом поддержку устаревших адаптеров REST/JSON/ActiveModel. Два основных изменения в обработке ошибок в Ember Data 1.13:

  • Более чистые hooks адаптера для ошибок
  • Использование формата объекта Error JSON API

Более чистые HOOKS адаптера для обработки ошибок

Ранее, если вы разделяли RestAdapter на подклассы, то могли переписать hooks ajaxSuccess и ajaxError, чтобы реализовать индивидуальную обработку ошибок. Но потенциальные ошибки могут принимать совершенно разные формы. Например, вы можете получить ответы с кодом состояния 200 в теле { error: error }. В таком случае сразу непонятно, что нужно написать код для обработки ошибки в методе ajaxSuccess. Из-за этого и многих других примеров, мы поняли, что ajaxSuccess и ajaxError — некорректный уровень, чтобы реализовать обработку ошибок.

В Ember Data 1.13 мы представили новый, упрощенный hook адаптера: handleResponse , а ajaxSuccess и ajaxError ушли на второй план.

Обязанность handleResponse — принять возвращенный статус, заголовки ответа, полезную нагрузку и решить, передать ли нагрузку или вернуть экземпляр AdapterError или InvalidError.

Например, если ваши API-инженеры по неизвестным причинам решили вернуть 200 OK с сообщением об ошибке, вы могли бы создать подкласс адаптера для обработки этой проблемы:

handleResponse: function(status, headers, payload) {
  if (status === 200 && payload.errors) {
    return new InvalidError(payload.errors);
  }
  return this._super(...arguments);
}

Вы также можете поделить на подклассы два метода помощника, isInvalid и isSuccess, чтобы индивидуально настроить случаи, в которых адаптеру считать запрос успешным или провальным.

Изначальная реализация isInvalid возвращает true, если код состояния http 422. Но вам может понадобиться другая семантика, чтобы, например, проверить свойство code на объекте ошибки JSON API.

Этот рефакторинг также позволяет абстрагировать объект jQuery jqXHR, который слишком тесно связывал Rest Adapter Ember Data с реализацией ajax jQuery. Новые hooks берут три аргумента вместо jqXHR: код состояния, хеш заголовков ответа и проанализированную полезную нагрузку. Это делает их независимыми от базовой реализации и позволяет легко использовать в будущем методы вроде fetch.

Использование формата объекта ошибки JSON API

Как и в остальной части Ember Data 1.13, мы реорганизовали обработку ошибок для использования JSON API. JSON API устанавливает формат объектов ошибок. Начиная с Ember Data 1.13, мы используем формат JSON API, чтобы передавать ошибки из адаптера в хранилище. Мы исключаем текущий гениальный формат Ruby on Rails для создания объектов InvalidError и заменяем его на подходящие объекты JSON API. В версии 1.13 старый формат сопровождается предупреждением об устаревшем элементе.

Устаревший формат:

new DS.InvalidError({
  first_name: ['is invalid']
});

Новый формат:

new DS.InvalidError([
  {
    source: { pointer: 'data/attributes/first_name' },
    detail: 'is invalid'
  }
]);

Спасибо @tchak и @twokul за работу над проектированием и реализацией нового API.

Важные устаревшие средства

Помимо новых особенностей Ember Data 1.13 сохраняет устаревшие средства для функций и поведения, которые удалят в Ember Data 2.0.

Асинхронные связи

В Ember Data 2.0 все связи по умолчанию будут асинхронными. Синхронные связи будут поддерживаться, но нужно вручную дать разрешение на их использование. Для этого необходимо установить на связи { async: false }. Ember Data 1.13 запишет предупреждение о нежелательном применении, если у вас будут связи, где не задано свойство async. Кроме того, вы можете использовать ember-watson, чтобы определить места в кодовой базе, где есть связи без заданного свойства async.

DS.STORE#FILTER перенесен в дополнение

С Ember Data 2.0 и ориентацией на сервер нас не устроило состояние текущего метода store.filter(). Сейчас он поддерживает ограниченное число сценариев использования, и зачастую он служит причиной утечек памяти в долго выполняемых приложениях. Чтобы дать Ember Data время на итерацию с улучшенным фильтром API, мы убрали текущий метод store.filter и перенесли его в дополнение https://github.com/ember-data/ember-data-filter/.

В Ember 2.0, если вы захотите использовать метод store.filter, вам будет нужно включить дополнение ember-data-filter в приложение.

DS.ACTIVEMODELADAPTER перенесен в дополнение

DS.ActiveModelAdapter и DS.ActiveModelSerializer также были перенесены в дополнение. Команда Ember Data продолжит их поддержку, но они не будут включены по умолчанию в Ember Data 2.0.

Индивидуальные хранилища

За годы работы Ember Data поддерживала ряд пространств имен, где можно задать индивидуальные хранилища. Для упрощения Ember Data 2.0 будет требовать, чтобы индивидуальные хранилища определялись в качестве служб.

Если в приложении Ember CLI у вас есть индивидуальное хранилище, которое определено в app/store.js, вам придется перенести его в app/services/store.js. Если индивидуальное хранилище находится в глобальном приложении, вам придется перенести его в App.StoreService.

Исходный адаптер JSON API

В Ember Data 2.0 адаптером по умолчанию будет JSONAPIAdapter. В Ember Data 1.13 при загрузке исходного RESTAdapter появится предупреждение об устаревшем элементе.

Чтобы убрать его и дальше использовать RESTAdapter, вам придется установить RESTAdapter в качества адаптера приложения.

app/adapters/application.js

import DS from 'ember-data';

export default DS.RESTAdapter;

Изменения store.push

Ранее Ember Data давала пользователям возможность добавлять запись в хранилище с помощью store.push('model-name', {}). Такой формат устарел, и теперь store.push будет принимать документ JSON API в качестве первого и единственного аргумента. Это новое изменение позволит Ember Data улучшить производительность в Ember Data 2.0 благодаря отсрочке создания экземпляров DS.Model, пока они не понадобятся пользовательскому коду. store.pushMany также устарел, так как теперь можно проводить множество записей с помощью документа JSON API.

rollback переименован в rollbackAttributes

record.rollback() устарел и уступил место record.rollbackAttributes(). Это новое имя более точно отражает его поведение и позволит в дальнейшем представить новый record.rollback(), который откатывает связи наряду с атрибутами.

isDirty переименован в hasDirtyAttributes

record.isDirty() устарел и был переименован в record.hasDirtyAttributes(). Это новое имя более точно соответствует его поведению и позволит в будущем представить новый record.hasDirtyRelationships() для проверки чистоты связей.

Предзагрузка данных записей в методах поиска

Если ранее вы использовали аргумент предзагрузки в store.find, то теперь в аргументе опций findRecord есть ключ предзагрузки.

// Deprecated
store.find('comment', 1, { post: 1 });

// Ember Data 1.13 style
store.findRecord('comment', 1, { preload: { post: 1 }});

Список изменений

Ember Data 1.13


Комментарии (0)

    Выделите опечатку и нажмите Ctrl + Enter, чтобы отправить сообщение об ошибке.