Первоначально опубликовано crunchingnumbers.live
В прошлую пятницу Эмбер 3.15 был Надоел октановое издание Отказ Чтобы увидеть, насколько легко (и весело) написание октанового приложения, я провел выходные, переписывая мои приложения Эмбер анимировал (v3.8) и Огни (v2.18) Отказ Позвольте мне поделиться, что я узнал.
Если у вас есть учебники и демонстрационные приложения, я призываю вас переписать их в октане. Вы можете опубликовать обе версии, чтобы помочь всем понять, как модель программирования в EMBER развивалась со временем.
Между ними эмбер анимировал представляет собой производственное приложение. Он имеет несколько сложных маршрутов, несколько компонентов, издевателей API и комплексной тестовой набор. Проблемы и радости, которые я столкнулся во время переписывания, вы, вероятно, также.
Я не использовал UMBER-CLI-UPDATE и CODEMOD, потому что у меня был несколько атипичный код от пробуждения витрины данных Ember и Ember Animated. Я полагал, написав новое приложение с нуля, я бы быстрее выучить октан.
- Приложение: 3.15 , 3.8.
- РЕПО: 3.15 , 3.8
- Сообщение в блоге: Анимация и предсказуемая нагрузка данных в Ember
. Шаги малыша
Я нашел постепенный подход, чтобы быть полезным. Представьте маршруты по одному за раз и посмотрите, какие компоненты должны быть мигрированы. После того, как компонент находится в октане, записи или порту через рендеринг тестов. После того, как все компоненты сделаны, напишите тесты приложений для маршрута. Перейдите на следующий маршрут и следующий набор компонентов. Промыть и повторить.
Часто вы найдете себе {{действие}} Модификаторы как смесь @action Декоратор, {{на}} Модификатор и {{fn}} помощник.
File: /app/templates/authors/details.hbs
Несмотря на то, что Verbose новый синтаксис помогает вам прояснить с вашим намерение . С практикой синтаксис станет вторым природой. Посетите гид EMBER, чтобы узнать больше Отказ
О соответствующем примечании, возьмите осторожность при преобразовании действий, называемых на представлении формы. (Я опущел параллелизм Ember в следующем примере, чтобы сделать точку зрения.)
File: /app/templates/search.hbs
{{действие}} Модификатор звонит Event.PreventDefault (); И предотвращает перезагрузку страницы для вас. В октане Вы выразить намерение предотвратить поведение по умолчанию. Вы можете найти событие объект как последний аргумент вашей функции.
File: /app/controllers/search.js
// Before
actions: {
searchStudents() {
const skillIds = this.selectedSkills.mapBy('id').join(',');
...
}
}
// After
@action searchStudents(event) {
event.preventDefault();
const skillIds = this.selectedSkills.mapBy('id').join(',');
...
}
б. Тестовые люксы
Вы можете Будьте уверены в перезаписи Если у вас есть существующие тесты. Поскольку мои 3,8 тесты уже последовали новой парадигме тестирования, мои тесты 3.15 нужны незначительное обновление: заменить Сервер С Это .server Для Ember Cli Mirage. Обратите внимание, что, в компоненте, помощниках и модификаторах, HBS это Теперь названный импорт .
File: /tests/integration/components/loading/component-test.js
// Before
import hbs from 'htmlbars-inline-precompile';
// After
import { hbs } from 'ember-cli-htmlbars';
Если у вас нет существующих тестов, я призываю вас занять время, чтобы написать их для вашего будущего себя. Узнайте больше о тестировании в Ember Отказ
с. Откуда приходят Foos?
Как только вы переписываете маршруты и компоненты, вы будете люблю, как вы явно называете вещи в шаблоне Отказ Нет больше путаницы, если {{foo}} это компонент, помощник, проходящий аргумент или местное свойство. (Теперь вы пишете , {{foo}} , @foo И this.foo , соответственно. Эмбер бросит полезную ошибку за забытые ошибки.)
File: /app/templates/students.hbs{{#if this.showHeader}}{{t "layout.students.header.students"}}
{{/if}}
Хотя вы видите этот код впервые, вы можете сказать, что это компонент, {{t}} это хелпер (перевод), @model проходящий аргумент, а Это .showheader это местное свойство. Вы знаете, какой файл смотреть рядом, чтобы узнать больше.
др. Компоненты только для шаблонов
Компоненты Glimmer Mermermer не создают «упаковку-дивы», так что вы можете попрощаться с название тэга , атрибуты мобинты , классы и Классические значения . Чаще всего, чем нет, они препятствовали мне разумному HTML-код быстро. После того, как вы удалите эти свойства, Улыбнись, когда вы видите, сколько компонентов не нуждается в подлоковом классе Отказ 6 из моих 10 компонентов стали только шаблон.
Одно предостережение с компонентами Glimmerer: Элитные , который был полезен для привязки этикетки к входу для доступности, больше не существует. Вместо этого используйте GUID для (этого) В классе Backing для создания идентификатора.
File: /app/components/skill-pill/component.js
import { guidFor } from '@ember/object/internals';
import Component from '@glimmer/component';
export default class SkillPillComponent extends Component {
inputId = `input-${guidFor(this)}`;
}
е. Модификаторы
Когда я готовлюсь в переписать, я не был уверен, что преобразую модификатор, который я использовал для демонстрации API веб-анимации. Я использовал Addon Ember-OO-модификаторы, но теперь я хотел использовать официальный Эмбер-модификатор Отказ
Для моего приятного сюрприза код оставался практически одинаковым. Новый модификатор даже, казалось, исправил анимационную ошибку, которую я видел раньше. Вы дошли до Дайте ура в укладственников Ember для после четко определенного API.
File: /app/modifiers/fade-up.js
import Modifier from 'ember-modifier';
export default class FadeUpModifier extends Modifier {
didReceiveArguments() {
const { duration, delay } = this.args.named;
this.element.animate(
[
{ opacity: 0, transform: 'translateY(60px)' },
{ opacity: 1, transform: 'translateY(0px)' }
],
{
duration: duration || 2000,
delay: delay || 0,
easing: 'cubic-bezier(0.075, 0.82, 0.165, 1)',
fill: 'backwards'
}
);
}
}
е. Избегать ярлыков
В 3.8 я создал результаты поиска – маршрут как ребенок поиска. В конце концов, пользователь сначала будет поискать, то увидите результаты. Гнездо, казалось, передал этот поток пользователя точно.
File: /app/router.js
Router.map(function() {
this.route('search', function() {
this.route('results');
});
});
Вложенность обычно подразумевает, что, когда пользователь находится на странице результатов, они также увидят страницу поиска. На самом деле приложение показывает только страницу результатов (что я хотел), потому что я использовал redertemplate обойти родитель.
Я не рекомендую эту практику с redertemplate на путь к изменению . Альтернативное решение так же просто и не загружает записи, которые никогда не используются в результатах поиска:
File: /app/router.js
Router.map(function() {
this.route('search');
this.route('search-results', { path: '/search/results' });
});
Пока вы переписали, я призываю вас к Вернитесь на счастливый путь, который проложен с передовой практикой Отказ Ваши будущие обновления будут проще. Вы также можете просмотреть амортизация Регулярно и обмениваются идеями для решений с людьми на Раздор Отказ
Между ними я нашел переписать это приложение, чтобы быть более интересным и вознаграждением. Это простое приложение с точки зрения компонентов: есть только 1 компонент. Тем не менее, потому что я написал его, пока я все еще был новым в EMBER и D3, приложение было пропущено с труднодоступным потоком управления. О, микс, CPS и наблюдатели …
Переписывая приложение с нуля, я должен понять, как разработать компонент D3, возможно, с учетом компоновки.
. Отслеживаемые свойства + Getters 💞
Отслеживаемые свойства Magic Отказ Вы больше не беспокоиться о том, должен ли компонент обновить вместе с тем, где, где, почему и как. Это просто работает. ™ Код слишком чище, потому что вы не указываете список зависимостей.
Следующий фрагмент показывает, как определить масштаб D3. Должен ли объект Numbuttons. или Доскаживание Изменение, масштаб будет пересматриваться и все, что зависит от масштаба также.
File: /app/components/lights-out/component.js
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { scaleLinear } from 'd3-scale';
export default class LightsOutComponent extends Component {
@tracked numButtons = { x: 5, y: 5 };
get boardSize() { ... }
get scaleX() {
return scaleLinear()
.domain([0, this.numButtons.x])
.range([0, this.boardSize.x]);
}
get scaleY() {
return scaleLinear()
.domain([0, this.numButtons.y])
.range([0, this.boardSize.y]);
}
}
Небольшой печать: обновление сложной структуры данных может потребоваться дополнительная работа. (Это всегда делало, чтобы быть справедливым.) Обновить Кнопки , двойной массив объектов, я сделал глубокую копию и использовал Установить :
File: /app/components/lights-out/component.js
import { set } from '@ember/object';
import { copy } from 'ember-copy';
export default class LightsOutComponent extends Component {
@tracked buttons;
toggleLights(i, j) {
let buttons = copy(this.buttons, true);
// Center
this.toggleLight(buttons[i][j]);
// Top, Bottom, Left, Right
...
this.buttons = buttons;
}
toggleLight(button) {
set(button, 'isLightOn', !button.isLightOn);
}
}
б. Модификаторы для спасения 💯
Во время перепиши я был волновался, что я снова испортил контрольный поток. В 2.18 я ввел микс и повернул слезю глаз к крючкам жизненного цикла Ember-13. Я также полагался на вычисленные свойства и наблюдатели, чтобы заставить поток мою.
Поскольку компоненты Glimmer имеют 2 Крючки жизненного цикла по умолчанию У меня было намного меньше работать с. Компонент D3 также необходим для изменения изменения размера окна. Я не был уверен, где я сейчас создаю и уничтожу слушателей событий.
Эти проблемы ушли, как только я обнаружил больше модификаторов. Ember-Render-модификаторы предоставляет {{Did-INSERT}} Модификатор и Ember-Did-Resize-Modifier {{DID-RESIZE}} модификатор.
Благодаря этим двум я смог Написать декларативный код без наблюдателя :
File: /app/components/lights-out/template.hbs...
Я могу посмотреть на этот шаблон и быть уверенным, что, когда элемент div добавляется в DOM, EMBER установит размер игрового контейнера, нарисовать игру, затем запустите ее. (Порядок внешнего вида уважается.) Аналогично, когда элемент div изменяет размер, Ember установит размер игрового контейнера и снова нарисовать игру.
Интересно, что, имея меньше, я мог сделать больше.
Октан, первое издание Ember, действительно сместилось в лучшую сторону, как разработчики будут обращаться к написанию, архитектуру и тестирование их приложений. Я видел проблеск, когда я переписал два приложения на выходных. Я с нетерпением жду, чтобы узнать больше о октане на работе, Встречи и Конференции В 2020 году!
С самого начала основное значение в пределах Ember была Ускорение (Усиление и т. Д. – Добавьте как можно больше каламбуров, связанных с октаном) ваше путешествие к производительности. Благодаря, казалось бы, маленьким вещам, таким как именованные аргументы и улучшены Эмбер Инспектор , а также большие, амбициозные вещи, такие как модификаторы и отслеживаемые свойства, Написание приложений в EMBER легко и весело.
Опять же, если у вас есть письменные учебники и демонстрационные приложения раньше, я призываю вас переписать их в октане и поделиться тем, что вы узнали. Если вы никогда не опробовали Ember раньше, вы можете начать с официальной, обновленной Учебник Super Rentals Отказ Не стесняйтесь просить о помощи на Раздор в любое время!
Если вы хотите узнать больше о октане, я призываю вас посетить эти ссылки:
- Октан здесь
- Ember.js Octane VS Classic Cheat
- Привлечение ясности шаблонам через эмбер октане
- Самые распространенные октановые ошибки Ember.js и как их избежать
- Эмбер Атлас: Рекомендуемый порядок миграции
- Эмбер октан – отлично подходит для начинающих (видео)
- Ember Octane Livestream: построить барабанную машину (видео)
Оригинал: “https://dev.to/ijlee2/rewriting-apps-in-ember-octane-1gic”