И правильно ли выбирать Angular в качестве интерфейса?

Как бы мы ни были взволнованы перед тем, как погрузиться в самую суть гештальт-задачи - четко объяснить данные в визуальной манере, - нам необходимо создать основу, чтобы заложить основу для нашей работы. Мы решили использовать Angular 1 для интерфейса и web.py в качестве серверной части, потому что они позволяют нам быстро прототипировать наши идеи (подробнее о решении для внешнего интерфейса в конце сообщения в блоге). Само собой разумеется, что мой путь с Angular начинается ухабисто. Я надеюсь, что поделившись ошибками, которые я допустил в Angular, вы сможете узнать, что такое Angular, и принять более обоснованное решение, когда уместно использовать Angular по сравнению с другим фреймворком.

Ошибка №1: несоблюдение «углового» подхода.

В Angular есть набор конкретных правил. Это просто потому, что он был создан как расширение HTML. Он следует мышлению HTML в том смысле, что вы хотите внести как можно меньше изменений в DOM. Для тех из вас, кто не знает, что такое DOM, вот краткое описание 101. DOM - это абстрактное воплощение веб-страницы в виде дерева. Изменение содержимого веб-страницы означает также изменение DOM. Вы должны помнить, какой компонент на веб-странице привязан к какой реализации. Это становится проблематичным для отслеживания, особенно если есть несколько компонентов, которые динамически изменяются на веб-странице. Angular упрощает манипуляции с DOM с помощью цикла дайджеста. Как по волшебству, он обнаруживает изменения и при необходимости модифицирует DOM. К сожалению, за это приходится платить: следуйте методике Angular или будьте готовы получить довольно неприятный код, который не обслуживается.

Руководства по стилю John Papa’s и Todd Motto - отличные справочные материалы, которые можно использовать, если вы не знакомы с шаблоном Angular. Это помогает создавать код, который легче поддерживать, отлаживать и масштабировать.

Еще одно частое последствие несоблюдения метода Angular - это наткнуться на код, который не работает должным образом. Одним из примеров этого является использование заглавных букв или подчеркивания в имени директивы на уровне HTML. Компилятор Angular не может принять это, потому что HTML нечувствителен к регистру, и поэтому Angular может ссылаться на директиву в DOM только в ее строчной форме. Чтобы усугубить путаницу, условное обозначение директивы - это camelCase в Javascript и разделение тире в HTML. Незнание этой мельчайшей детали может легко увести вас от реального решения.

Так что помните, следуйте пути Angular. Или Angular просто скажет вам ехать по шоссе.

Ошибка № 2: думать, что он похож на другие интерфейсы.

Поскольку Angular предоставляет структуру, необходимую для разработки веб-приложения, начать работу с Angular очень просто. Только позже, когда вам потребуется более богатая функциональность в своем приложении, вы поймете, что вам нужно время, чтобы по-настоящему понять внутреннюю работу Angular. Я был недальновиден и думал, что могу перенести свои знания на другие интерфейсные фреймворки. Боже, меня ждал сюрприз! Angular 1 не только отличается от React и Ember, но и сильно отличается от Angular 2 тем, что можно сказать, что это две отдельные интерфейсные среды!

Я могу представить, насколько сложно может быть интегрировать существующие проекты с другими интерфейсными фреймворками, отличными от Angular. К счастью для нас, мы не решаем эту проблему.

Ошибка № 3: Группировка файлов по типу и функциям

Angular использует Model-View-Controller (MVC). Прелесть этой методологии заключается в разделении задач, при которых задания, обрабатывающие пользовательский интерфейс, отделены от тех, которые обрабатывают логику приложения. Как показано на диаграмме выше, контроллер обрабатывает все запросы для приложения (т. Е. Пользователь нажимает на визуальную диаграмму). Затем он связывается с моделью для извлечения любых данных, необходимых для представления. Представление использует данные, подготовленные контроллером, для создания правильного отображения для запроса (т. Е. Пользователь нажимает на визуальную диаграмму - ›диаграмма увеличивает масштаб этой конкретной цели с дополнительной информацией).

Angular использует другое соглашение об именах, чем стандартный Model-View-Controller. Его можно резюмировать следующим образом:

  • Служба (модель): служба связывается с серверной частью для получения данных, запрошенных контроллером. Поскольку это синглтон, он сохраняется в течение всего времени существования приложения. $scope затем используется в контроллере как контейнер модели.
  • Директива (просмотр): директива обрабатывает окончательную презентацию, отображаемую пользователю после того, как контроллер извлечет необходимую ему информацию из службы. Директива должна быть единственной, которая управляет DOM.
  • Контроллер (Контроллер): Контроллер запрашивает необходимые данные у службы и привязывает их к $scope для использования в представлении. Он может управлять сложной логикой, но должен быть сведен к минимуму до обрабатываемого запроса. Из-за этого контроллер работает столько, сколько требует его вариант использования.

Зная, что Angular использует фреймворк Model-View-Controller, впервые может показаться правильным сгруппировать файлы по их соответствующим типам.

DO NOT FOLLOW THIS EXAMPLE
app/
    app.js
    config.js
    Service/
        LoginService.js
        WorkspaceService.js
    Directive/
        LoginDirective.js
        WorkspaceDirective.js
    Controller/        
        LoginController.js
        WorkspaceController.js
    HTML/
        login.html
        workspace.html

Но каталог, подобный приведенному выше, становится все труднее отслеживать с каждой дополнительной функцией. Это также верно для новых членов команды, которые не знакомы со всеми функциями, которые может предложить проект. Лучший способ структурировать каталог - сгруппировать по функциям и разместить необходимый MVC в указанной папке.

app/
    app.js
    config.js
    Login/
        login.html
        LoginController.js
        LoginDirective.js
        LoginService.js
    Workspace/
        workspace.html
        WorkspaceController.js
        WorkspaceDirective.js
        WorkspaceService.js

Как видите, вы можете сразу найти то, что ищете, и наметить, какие функции имеет проект (без необходимости погружаться прямо на страницу документации). Победа!

Ошибка # 4: раздутый контроллер

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

Давайте забудем, что у нас даже была эта мысль. Поскольку контроллер координируется с представлением и моделью, он должен быть минимальным, чтобы упростить тестирование. Он никогда не должен делать то, что делает директива (манипулировать DOM), и никогда не должен хранить какие-либо данные, подобные тем, что делает служба. Контроллер забудет о данных после того, как приложение перейдет в другое состояние, поэтому хранить данные в контроллере нельзя. Даже если вам удалось сохранить его в localStorage, это намного медленнее, чем сохранение его в переменной Javascript, например $scope.

Пример, когда я столкнулся с такой проблемой, - это когда я пытался заставить контроллер обрабатывать то, что должно было быть заданием для директивы. После того, как контроллер предоставит список данных в шаблон HTML, я хотел пройтись по списку и вызвать функцию для каждого элемента в списке. В то время я предполагал, что контроллер является вдохновителем всей логики представления. Это было неправильное предположение, потому что после передачи данных от контроллера в представление задача директивы - обрабатывать любые изменения в представлении. Как только эта интуиция MVC заложена в мое основное мышление, все становится на свои места.

Ошибка № 5: обработка асинхронных вызовов

Самый удивительный аспект, который заставил меня задуматься, - это идея асинхронных вызовов в Javascript. В основном Javascript работает в одном потоке вашего браузера. Если я принудительно запустил Javascript по порядку, он будет ждать завершения одного вызова, прежде чем перейти к следующему. Затем пользователь вынужден взаимодействовать с неотвечающим приложением. Вот почему Javascript - это асинхронный способ, позволяющий поддерживать отзывчивость приложения. Это замечательно, когда вы пытаетесь разработать платформу визуализации данных, которая выполняет несколько вызовов ввода-вывода для извлечения данных и, возможно, имеет несколько пользователей, взаимодействующих с одним и тем же полем.

Если бы вызов ввода-вывода зависел от предыдущего вызова ввода-вывода, как бы вы сделали это в Angular асинхронно? Вы можете связать их. Вы также можете запустить параллельные вызовы ввода-вывода перед выполнением логики над этими данными. Burleson Thomas написал в блоге отличный пост о том, как этого добиться.

Ошибка №6: слишком много смотрю

Вы помните, как это было волшебно, когда вы впервые обнаружили двустороннюю привязку данных в Angular? Без строчки кода вы можете сделать элемент полностью динамическим, изменив значение в $scope. Но здесь таится скрытая проблема, которую я даже не предвидел. Прежде чем мы пройдем этот авантюрный путь, давайте попробуем лучше понять двустороннюю привязку данных, чтобы мы знали, в чем заключается эта потенциальная проблема.

Хранение состояния приложения внутри DOM обычно является плохой практикой, потому что представление не должно хранить данные. Итак, где мы можем сохранить состояние приложения, если мы не можем сохранить его в DOM? Конечно, мы можем сохранить это в Javascript! Но что, если пользователь захочет просмотреть полученные данные? Хм, я думаю, мы можем сохранить это в DOM? В этом заключается прелесть двусторонней привязки данных.

Поскольку Angular сохраняет состояние приложения как в Javascript, так и в DOM и очень быстро синхронизируется между ними (как показано на изображении выше), вы можете динамически изменять элемент без добавления строки кода. Но с увеличением сложности приложения количество элементов увеличивается, и иногда вы хотите добавить наблюдателя к элементу, чтобы выполнять дополнительную логику поверх него. Со временем ваше приложение может быть переполнено зомби-наблюдателями, ожидающими изменений в соответствующем элементе. Это съедает ресурсы вашего браузера, и ваше приложение становится медленным. Это может быть особенно плохо, когда вы создаете приложение на мобильных устройствах.

Решение этой проблемы - по возможности избегать наблюдателей. Кто сказал, что слишком много просмотра может быть вредным для вас? Сказал Angular. И если вы знаете, что для вас хорошо, всегда следуйте указаниям Angular (или вы можете перейти на Angular 2, который пытается решить эту проблему). И пожалуйста, не ставьте наблюдатель в контроллер. Он уже раздулся.

Почему тогда стоит выбрать Angular 1?

Для тех, кто плохо знаком с фронтенд-разработкой, Angular - хорошее место для начала. Это не быстрый способ начать, потому что требуется значительная кривая обучения, которую нельзя перенести на другие интерфейсные фреймворки. Даже его преемник Angular 2 отличается от Angular 1.

Поскольку Angular 1 использует цикл дайджеста для обновления своего представления, его производительность временами может быть сомнительной. Angular 2 якобы устраняет эту проблему с производительностью, заменяя цикл дайджеста (в процессе двусторонней привязки данных) алгоритмом обнаружения изменений, который может проверять, изменилась ли привязка, и избегать сканирования частей дерева DOM, которые не изменились. Себастьян Пейротт сравнил производительность Angular 1 с Angular 2, а также другими интерфейсными фреймворками, если вам интересно.

Так почему мы выбрали Angular 1 вместо Angular 2? Или Angular 1 вместо Ember с Flux? О стабильном выпуске Angular 2 было объявлено после начала гештальт-челленджа. Поскольку это относительно недавний выпуск, мы знаем, что должны регулярно обновляться и приспосабливаться к каждому новому обновлению. Наша цель в гештальте - выяснить, как ясно и наглядно объяснить данные. Мы стараемся свести к минимуму нарушения в процессе работы, выбирая Angular 1. Но, если у нас будет второй шанс сделать это снова и снова, мы будем использовать Angular 2. Angular 2 имеет лучшую производительность и адаптирован не только для браузеров. на рабочем столе, но также и в браузерах на мобильных устройствах.

Что касается Ember с Flux, у нас еще не было возможности их изучить. Это будет хорошей практикой в ​​будущем. И Angular, и Ember могут быть объединены с D3.js (и другими инструментами визуализации данных) для создания платформы, необходимой для визуализации - и, что более важно, объяснения - данных.

Lab41 - это испытательная лаборатория Кремниевой долины, где эксперты из разведывательного сообщества США (IC), академических кругов, промышленности и In-Q-Tel собираются вместе, чтобы лучше понять, как работать с большими данными и в конечном итоге использовать их.

Узнайте больше на lab41.org и подпишитесь на нас в Twitter: @ _lab41