Проект в песочнице на Ember.js
План ознакомительного доклада для команды разработчиков.
Знакомство с ember
- Ember.js - это фреймворк для создания SPA
- Делать некий туториал не имеет смысла, ибо таковой есть на официальном сайте
- Прихожу к выводу, что нет фреймворков, которые как гласят их лозунги, простые и лёгкие для использования. За сколькие брался - везде найдутся подводные камни, которые заберут уйму времени и попортят крови. Погружение в Ember заняло недели 2.
- В целом мои ощущения положительные
- Лучше расскажу от подходе к написанию проекта.
Описание проекта
- Табель рабочего времени. Замена имеющегося решения в plain xls
- Несколько команд или отделов
- Многопользовательский режим
- Примитивная отчётность
https://github.com/patgod85/timesheet2
Архитектура и технологии
- Есть серверная часть на Symfony2, Doctrine ORM и Mysql
- В базе хранятся данные календарей в формате ical
- Календари есть для компании, команды и сотрудника
- На клиенте парсятся календари и отображается содержимое
- Взаимодействие между клиентом и сервером при помощи REST API
- Для эксперимента для реализации клиента выбран Ember.js 2
Подход к написанию client side на Ember
- Разворачивается проект из командной строки. Я помещаю его в папку /src-client
- Имеется и подразумевается использование EmberData для получения данных с сервера
- Adapters существуют для настройки получения данных с сервера, выбора формата REST протокола
- Для тестовых целей есть mirage, который будет мочить данные
- На клиенте мы описываем модели, которые будут использованы для мапирования данных с сервера
- Сущности, которыми Ember оперирует для построения UI: routes (controllers), components, helpers
- Ember - маршрутоориентированный, всё отталкивается от маршрутов
- Маршруты реализованы не после #, как мне удавалось видеть в других фреймворках, а как привычный URL
- Создадим новый маршрут в ember-cli:
ember g route routename
- Ember-cli - вспомогательная командная строка, которыми снабжаются многие фреймворки сейчас
- Существует масса дополнения, которые удобно ставятся через ember-cli. Кроме того можно установить сторонние библиотеки, вроде moment.js
- Удалим созданный маршрут
ember destroy route routename
- В файле
routes.js
содержится описание маршрутов и их иерархия - Итак наш маршрут создан, следующий этап - это получение данных. Мы обращаемся к сервису store, он подобно ORM, смотрит свой репозиторий и либо берёт из данные него либо делает запрос на сервер. Можно посмотреть пример получения данных в маршруте Employee.js
- Запрос данных обёрнут в промис
- Когда данные подготовлены, можем отобразить их в представлении, в папке templates. Место положение шаблонов определяется соглашением. Движок для шаблонов - HBS.
- Стоит отметить удобную возможность указания шаблона для тех случаев, когда представление “ожидает”. Просто создадим рядом шаблон routename-loading.hbs и его содержимое будет показываться пока не резолвятся промисы по загрузке модели.
- Связывание компонентов и моделей двунаправленное, но можно организовать и однонаправленное.
- При помощи actions мы можем управлять состоянием компонентов и изменять данные.
При изменении данных и вызове
model.save()
, они автоматически отправятся на сервер, при необходимости. Кроме того есть сервис Router предоставляющий методtransitionTo(routename)
для смены маршрута - Когда стек Route -> Template готов, можем запустить наше приложение. Для этого воспользуемся
ember server
- Дальше остаётся писать код
- После первых шагов поразило, что нет хелпера для drop down из коробки. Нужно написать его руками.
Дальнейшее погружение
- После первых шагов и нескольких рабочих страничек возникают некоторые проблемы, связанные с тем, что плохо разобрался в подходе к работе с данными
- Для того чтобы ember в runtime перерисовывал только изменившиеся элементы интерфейса, нужно правильно подходить к связыванию.
В частности массивы и объекты оформлять как объекты Ember. Использовать
Ember.Object.create
и.pushObjects()
- Использовались
Ember.computed
иEmber.observable
, они принимают список сущностей от которых зависят. При зависимости от массивов существует специальный синтаксис позволяющий проверять только определённые свойства у элементов массивов, например - Важно массивы данных не перезаписывать при изменении их элементов, а корректировать при помощи таких методов как
map
- Для вынесения некоторой логики в отдельный слой, например парсинг ical, использовались сервисы.
- Использование сервисов реализуется через DI.
- Можно настроить инжектирование сервисов в Initializers, например для всех компонентов, а можно в конкретном компоненте инжектировать сервис при помощи
Ember.inject.service('servicename')
- По моему скромному мнению, удобно организовано тестирование. Каждый модуль тестируется, при этом применяются слегка разнообразные подходы. В папке tests тесты структурированы по этим подходам. Как это ни странно, я даже пишу и запускаю тесты перед пушами.
- Для тестирования компонентов используется запуск движка HBS.
Бесполезные выводы
Из минусов:
- Достаточно медленный. Конечно нужно сделать поправку на кривые руки, но в моём приложении для команды из 9 человек, расписание на 1 месяц = 31*9, то есть порядка 300 экземпляров компонентов. Строится почти 3 секунды. Это весьма неприятно. Имеются техники по оптимизации их я хочу пощупать ближайшем будущем.
- У меня на Windows, при использовании
ember server
, после исправления файла в phpStorm и перехода фокуса на браузер, страница автоматически перезагружается только через пару секунд. Но я не искал пока методов ускорения сборки.
Из плюсов:
- Весьма читаемый код и наглядная структура проекта
- Удобная инфраструктура разработки
- Удобное тестирование