Руководство по стилю готовит ваш проект к Angular 2 и масштабируемости.

TL;DR

Приложение со всеми изменениями можно найти на github.

Авторские бредни

Когда вы запускаете новое приложение Ionic, вы получаете довольно стандартный макет Angular с 3 файлами JS — приложением, контроллером и службами. Внутри каждого файла команды объединены в цепочку, превращая каждый файл в эквивалент одной гигантской строки кода. Если вы используете этот макет, вы в конечном итоге столкнетесь с проблемами с большими неуправляемыми файлами. Мы собираемся разбить каждый компонент на отдельный файл и очистить то, как они прикреплены к модулю приложения.

Использование Руководства по стилю сделает ваш код Angular 1 более похожим на код Angular 2. Во многих случаях вы даже сможете повторно использовать целые сервисы, потому что будете использовать чистый JS. Использование чистого JS также облегчит тестирование вашего кода. Все это значительно упростит переход на V2, когда через месяц или два он станет менее увлекательным.

Руководство по стилю превратилось в настоящее чудовище, но оно того стоит. Даже если вы просто используете аспекты, которые я изложил здесь, у вас будет отличное начало. И, честно говоря, я сам не следую всему, что рекомендует руководство по стилю, а только низко висящим фруктам.

Актуальная полезная информация

Мы начнем с предположения, что у вас установлены NPM и Ionic. Начнем с создания нового приложения.

ionic start my_app
cd my_app
ionic serve

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

Единая ответственность и соглашения об именах

У нас должен быть только один компонент приложения для каждого файла. Каждый из наших компонентов нужно будет переместить в отдельный файл.

Каждое имя файла должно иметь формат feature.type.js и должно совпадать с именем компонента. Таким образом, avengers.controller.js будет содержать AvengersController.

Давайте откроем наши 3 файла и посмотрим, какие компоненты нужно превратить в новые файлы.

app.js
Этот файл содержит объявление модуля, функцию запуска и функцию конфигурации, используемые для маршрутизации и обслуживания состояния. Мы создадим 2 новых файла и каталог. Затем мы переместим app.js в новый каталог.

www/js/app/app.js
www/js/app/app.run.js
www/js/app/routing.config.js

Убедитесь, что www/index.html отражает ваши изменения:

<script src="js/app/app.js"></script>
<script src="js/app/app.run.js"></script>
<script src="js/app/routing.config.js"></script>

Не забывать поддерживать index.html в актуальном состоянии — это ваша работа в будущем.

controllers.js
У нас также не должно быть единой папки для контроллеров. Папки должны быть созданы для логической организации вашего приложения, а не для поиска файлов на основе типа компонента. Это означает, что мы не будем создавать новую папку для контроллеров, а просто поместим их в папку JS, чтобы организовать их позже по мере роста приложения.

www/js/dash.controller.js
www/js/chats.controller.js
www/js/chat-detail.controller.js
www/js/account.controller.js

services.js
Создайте:

www/js/chats.factory.js

Модули

Модули должны использовать систему получения/установки. Они также должны быть отделены от своих компонентов, но мы займемся этим позже. Установить с:

angular.module('app', ['requirement1', 'requirement2']);

И получить с:

angular.module('app');

Переместите функцию запуска из app.js в app.run.js.

Разделите связанную функцию .run() на отдельную функцию:

function appRun($ionicPlatform) {
  $ionicPlatform.ready(function() {
    // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
    // for form inputs)
    if (window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) {
      cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
      cordova.plugins.Keyboard.disableScroll(true);
}
    if (window.StatusBar) {
      // org.apache.cordova.statusbar required
      StatusBar.styleDefault();
    }
  });
}

Затем внизу файла добавьте геттер вашего модуля.

angular
  .module('starter')
  .run(appRun);

Сделайте то же самое для routing.config.js:

function routingConfig($stateProvider, $urlRouterProvider) {
...
}
angular
  .module('starter')
  .config(routingConfig);

Единственное, что осталось в вашем app.js, должно быть:

angular.module(‘starter’, [‘ionic’, ‘starter.controllers’, ‘starter.services’]);

Контроллеры и область действия контроллера

С перекрывающимися контроллерами легко перепутать переменные, поэтому мы будем использовать контроллер как объект, а не $scope. Таким образом, вместо просто {{variable}} у нас будет {{controllerName.variable}}.

Во-первых, сделайте с controllers.js то же самое, что и с app.js. Разделите каждую связанную функцию в отдельный файл и преобразуйте ее в обычную функцию. Единственная разница в том, что вы должны назвать свой контроллер. (Не забудьте обновить ваш index.html.)

Вот как должен выглядеть dash.controller.js:

function dashController() {
}
angular
  .module('starter')
  .controller('DashController', dashController);

Это сломает ваше приложение, потому что мы изменили имя с DashCtrl на DashController. Откройте routing.config.js и найдите объявление состояния tab.dash. Измените атрибут контроллера следующим образом:

controller: ‘DashController’,
controllerAs: ‘dash'

Теперь сделайте то же самое для контроллера чатов, не забыв обновить routing.config.js:

function chatsController(Chats) {
  var controller = this;
  //changed variable to avoid chats.chats
  controller.chatList = Chats.all();
  controller.remove = function(chat) {
    Chats.remove(chat);
  };
}
angular
  .module('starter')
  .controller('ChatsController', chatsController);

ВАЖНЫЙ! Мы используем «var controller = this;», потому что «это» будет переопределено внутри анонимной внутренней функции. Присвоение его переменной гарантирует, что оно будет доступно из любого места внутри контроллера.

Если вы перейдете на страницу чатов, данные не будут отображаться. Это потому, что мы убрали область действия в пользу именованного контроллера. В дальнейшем везде, где у нас обычно есть переменная с областью действия, нам нужно будет использовать имя контроллера, как объявлено в controllerAs. Откройте tab-chats.html и измените элемент ion, чтобы использовать имя контроллера.

<ion-item class="item-remove-animate item-avatar item-icon-right" ng-repeat="chat in chats.chatList" type="item-text-wrap" href="#/tab/chats/{{chat.id}}">

Надеюсь, теперь вы освоились. Идите вперед и почините остальные ваши контроллеры.

Услуги

Ничего особенного в обслуживании. Если вы дошли до этого места, вы должны сами в этом разобраться. Но вот как выглядит chats.factory.js:

function chatsFactory() {
...
}
angular
  .module('starter')
  .factory('ChatsFactory', chatsFactory);

Единственная загвоздка в том, что мы переименовали Chats в ChatsFactory, поэтому вам нужно обновить зависимость chats.controller.js.

Развязка и очистка

Мы отделили модуль, когда каждый компонент ссылался на модуль, а не наоборот. Это позволит нам перемещать компоненты в другие проекты и нужно будет только изменить имя модуля. Давайте отразим это изменение в app.js, удалив зависимости от наших собственных модулей. Теперь ваш app.js должен выглядеть так:

angular.module(‘starter’, [‘ionic’]);

Приятно!

Теперь вы можете безопасно удалить services.js и controllers.js из каталога и вашего индексного файла.