Статьи

Начало работы с Ionic: компоненты JavaScript

Конечный продукт
Что вы будете создавать

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

Термин «компоненты» несколько злоупотребляет при разработке внешнего интерфейса, поскольку многие фреймворки имеют собственное понятие, описывающее компонент. Фактически, веб-компоненты как официальный стандарт HTML могут еще больше усложнить концепцию, поэтому давайте четко определим, что такое компонент в Ionic.

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

В Ionic есть два типа компонентов: CSS и JavaScript . Компоненты CSS реализованы в виде набора классов CSS, которые изменяют элемент, чтобы придать ему особый вид, например панель заголовка.

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

В этом уроке мы сосредоточимся на некоторых компонентах JavaScript. Позже в этой серии мы подробнее рассмотрим компоненты CSS.

Иногда Ionic реализует компонент как компонент CSS, так и компонент JavaScript, например компонент вкладок. Это означает, что вы решаете, какой из них использовать. Я обычно рекомендую выбрать реализацию JavaScript. В большинстве случаев затраты на использование компонента JavaScript незначительны, и я считаю, что они облегчают работу с вашим кодом.

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

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

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

Вы можете просмотреть запущенное приложение на Heroku и просмотреть завершенный проект на GitHub . Тем не менее, я призываю вас следовать и создать приложение со мной.

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

1
ionic start civinfo https://github.com/ionic-in-action/starter

Это загружает стартовый пакет, который включает пустой шаблон Ionic, чтобы начать нас (созданный для использования с моей книгой Ionic в действии ). Введите каталог, cd civinfo и запустите ionic serve .

Теперь вы можете просмотреть пустую загрузку приложения по адресу http: // localhost: 8100 (или по порту, установленному Ionic). Я рекомендую открыть инструменты разработчика вашего браузера, чтобы убедиться, что вы видите пустой экран. Да, это должен быть белый экран. Я также предлагаю использовать эмуляцию устройства Chrome при предварительном просмотре приложения.

Навигация настолько важна, что мы должны начать с разработки нашего приложения. Основными компонентами навигации являются ionNavBar и ionNavView . Большинство приложений имеют функцию дизайна, в которой есть панель навигации с различными заголовками и кнопками действий, а затем остальная часть области посвящена содержимому для текущего представления.

ionNavBar   и компоненты ionNavView предоставляют эту функциональность с некоторыми встроенными интеллектуальными возможностями, чтобы помочь нам. В конце концов, наше приложение будет иметь несколько маршрутов, но в этом уроке мы создадим только один.

Ionic использует UI Router для управления навигацией и маршрутизацией. Если вы знакомы с ним, то вы узнаете реализацию в Ionic. Здесь много нюансов, но в этом уроке все будет просто. Наиболее распространенное и простое использование — определить каждую из различных страниц вашего приложения как состояние , которое является способом Ionic / UI Router для определения конкретного представления.

Для начала, мы сначала включаем два навигационных компонента в www / index.html, как вы видите ниже, размещая его внутри тела.

1
2
3
4
<body ng-app=»App»>
  <ion-nav-bar class=»bar-balanced»></ion-nav-bar>
  <ion-nav-view></ion-nav-view>
</body>

После добавления кода в index.html вы можете перезагрузить приложение, и в верхней части приложения должна появиться зеленая полоса.

Приложение показывает только панель навигации, которая зеленая

Вы определили компонент ionNavBar , который автоматически появляется в верхней части экрана. Позже, когда мы создадим отдельные представления, эти представления смогут передавать заголовок и дополнительные кнопки для отображения. Он достаточно умен, чтобы знать, какой должна быть панель навигации для разных устройств. Это не одинаково для разных платформ, поэтому это очень полезно. Панель навигации имеет класс bar-balanced чтобы придать ей зеленый цвет.

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

Компоненты навигации являются примерами компонентов JavaScript (также известных как угловые директивы). Они выглядят как пользовательские теги HTML и, при совместном использовании, они достаточно умны, чтобы синхронизировать строку заголовка с текущим представлением и отображать правильный контент на основе выбора навигации пользователя. Чтобы увидеть это в действии, нам нужно добавить несколько состояний. Давайте начнем с создания нашего первого состояния, которое отображает список парков.

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

  • обновить панель навигации заголовком
  • загрузить список парков из API
  • отобразить список элементов в формате, удобном для мобильных устройств
  • разрешить загрузку большего количества элементов при достижении дна с помощью бесконечной прокрутки
  • отображать изображение с каждым элементом

Теперь, когда у нас есть несколько целей для этого представления, давайте начнем с добавления нашего файла JavaScript, который зарегистрирует это представление. Создайте новый файл place.js по адресу www / views / place / и добавьте в него следующее:

01
02
03
04
05
06
07
08
09
10
angular.module(‘App’)
.config(function($stateProvider) {
  $stateProvider.state(‘places’, {
    url: ‘/places’,
    controller: ‘PlacesController as vm’,
    templateUrl: ‘views/places/places.html’
  });
})
.controller(‘PlacesController’, function() {
});

Мы объявляем новое состояние для маршрутизатора пользовательского интерфейса, используя метод $stateProvider.state() . Это доступно только для настройки внутри метода Angular angular.config() . Когда вы объявляете состояние, вы сначала передаете строку для имени маршрута, в данном случае places . Затем вы передаете объект с различными свойствами, которые определяют состояние, например, URL, контроллер и шаблон. Вы можете посмотреть в документации по UI Router все возможные варианты конфигурации.

Мы объявили новое состояние, назвали его places , присвоили ему URL-адрес или мест , назвали controller используя controller as синтаксиса , и перечислили templateUrl для загрузки. Это довольно распространенное определение состояния, и вы видите, что оно используется практически таким же образом с другими состояниями. Контроллер, объявленный здесь, пуст, но мы скоро добавим к нему.

Этот шаблон является важной частью представления и описывает визуальные аспекты этого представления. Большая часть логики и поведения представления будет управляться в контроллере и шаблоне. Наше государство заявляет, что мы хотим загрузить HTML-файл для шаблона, но мы еще не создали его. Давайте исправим это, создав новый файл place.html по адресу www / views / place / и добавив приведенный ниже код.

1
2
3
4
<ion-view view-title=»Local Parks»>
  <ion-content>
  </ion-content>
</ion-view>

Пока что в этом шаблоне мы объявили компоненты ionView и ionContent . Компонент ionView — это оболочка, которую вы помещаете вокруг шаблона, который предназначен для загрузки в компонент ionNavView мы объявили ранее. Атрибут view-title также используется для передачи заголовка, который должна отображать панель навигации.

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

Теперь нам нужно убедиться, что приложение загружает скрипт для выполнения, добавив place.js в index.html, как показано ниже. Я рекомендую добавить это прямо перед </head> .

1
<script src=»views/places/places.js»></script>

Вы можете просмотреть приложение, но вы все равно не увидите его отображение. Чтобы увидеть представление, перейдите по адресу http: // localhost: 8100 / # / place . URL-адрес, указанный в определении состояния, можно использовать для перехода к маршруту. Затем он должен выглядеть так, как показано на следующем рисунке, с названием «Местные парки».

App Places View Отображение заголовка в панели навигации

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

Прежде чем мы сможем многое сделать, нам нужно загрузить некоторые данные. Для этого нам нужно добавить сервис Angular, который поможет нам управлять геолокацией. В будущем учебнике местоположение пользователя будет определяться устройством. До тех пор мы собираемся вручную установить его в Чикаго, один из моих любимых городов.

Откройте www / js / app.js и добавьте следующую службу в конец файла. Он должен angular.module с существующими методами из angular.module .

01
02
03
04
05
06
07
08
09
10
11
12
.factory(‘Geolocation’, function() {
  return {
    «formatted_address»: «Chicago, IL, USA»,
    «geometry»: {
      «location»: {
        «lat»: 41.8781136,
        «lng»: -87.6297982
      }
    },
    «place_id»: «ChIJ7cv00DwsDogRAMDACa2m4K8»
  };
})

Это служба Angular, которая возвращает объект, который соответствует тому, что API Google Maps возвращает для Чикаго. Теперь у нас есть детали для местоположения, чтобы мы могли загружать парки там.

Далее мы собираемся обновить контроллер для загрузки списка из API. Для простоты я загружаю данные, используя сервис $http в контроллере. Лучшей практикой будет абстрагирование этого в сервис. Снова откройте www / views / place / place.js и обновите контроллер следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
.controller(‘PlacesController’, function($http, Geolocation) {
  var vm = this;
  var base = ‘https://civinfo-apis.herokuapp.com/civic/places?type=park&location=’ + Geolocation.geometry.location.lat + ‘,’ + Geolocation.geometry.location.lng;
  vm.places = [];
  
  vm.load = function load() {
    $http.get(base).then(function handleResponse(response) {
      vm.places = response.data.results;
    });
  };
  
  vm.load();
});

Контроллер имеет метод vm.load() для выполнения HTTP-запроса и сохраняет результаты в vm.places . Когда вы сохраните это, вы увидите запуск HTTP-запроса в инструментах разработчика вашего браузера. Даже если вы знакомы с Angular, вы можете не распознать этот точный подход для хранения данных в переменной vm . Я рекомендую просмотреть пост Джона Папы о том, почему это рекомендуемый подход, если вам нужна некоторая ясность.

Чтобы отобразить данные, нам также необходимо обновить шаблон и перебрать список парков для их отображения. Откройте www / views / place / place.html и обновите его, как показано ниже.

01
02
03
04
05
06
07
08
09
10
11
<ion-view view-title=»Local Parks»>
  <ion-content>
    <ion-list>
      <ion-item ng-repeat=»place in vm.places» class=»item-avatar»>
        <img ng-src=»{{place.icon}}» />
        <h2>{{place.name}}</h2>
        <p>{{place.formatted_address}}</p>
      </ion-item>
    </ion-list>
  </ion-content>
</ion-view>

В шаблоне мы используем компоненты ionList и ionItem . Компонент ionList является одним из наиболее полезных компонентов, поскольку списки являются очень распространенным вариантом дизайна в мобильных устройствах из-за небольших экранов и типичного использования в портретной ориентации. Как и список, использующий ul и li , ionList любое количество элементов ionItem .

Списки могут принимать различные виды, и в этом примере элемент списка отображает изображение слева, объявляя класс item-avatar на ionItem . Тот же подход может быть использован в приложении обмена сообщениями, где у вас есть список чатов с аватаром каждого человека.

Внутри ionItem вы отображаете имя и адрес. Стиль по умолчанию — автоматически обрезать (используя CSS) любой текст, который переполняется, чтобы элементы были одинаковой высоты.

Приложение показывает все элементы в списке

Мы загрузили список парков и отобразили их в виде списка с использованием ionList и ionItem . Мы можем сделать еще один шаг вперед и добавить бесконечную прокрутку для загрузки дополнительных результатов, когда пользователь прокручивает в конце списка (если они доступны).

Чтобы в списке автоматически загружались дополнительные элементы на основе прокрутки пользователем вниз, мы можем использовать компонент ionInfiniteScroll . Этот компонент помещается в конец списка, отслеживает, когда пользователь прокрутил до конца, а затем вызывает метод, который может загружать дополнительные элементы. Он также имеет встроенный загрузочный счетчик, который показывает, что загружается больше элементов. Спиннер скрыт, когда ответ разрешается.

Наш API также должен поддерживать некоторую форму нумерации страниц, чтобы это работало. В этом случае API Карт Google предоставляет токен, который необходимо передать для загрузки следующего набора результатов. Нам нужно обновить контроллер для управления этой логикой, поэтому давайте начнем с обновления www / views / place / place.js, как показано ниже.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.controller(‘PlacesController’, function($http, $scope, Geolocation) {
  var vm = this;
  var base = ‘https://civinfo-apis.herokuapp.com/civic/places?type=park&location=’ + Geolocation.geometry.location.lat + ‘,’ + Geolocation.geometry.location.lng;
  var token = »;
  vm.canLoad = true;
  vm.places = [];
  
  vm.load = function load() {
    var url = base;
    if (token) {
      url += ‘&token=’ + token;
    }
  
    $http.get(url).then(function handleResponse(response) {
      vm.places = vm.places.concat(response.data.results);
      token = response.data.next_page_token;
  
      if (!response.data.next_page_token) {
        vm.canLoad = false;
      }
      $scope.$broadcast(‘scroll.infiniteScrollComplete’);
    });
  };
});

Мы добавили новое свойство vm.canLoad , которое является логическим значением, которое указывает, есть ли дополнительные элементы для загрузки. Это true по умолчанию. Пока запрос не будет возвращен, мы не знаем, есть ли в наличии дополнительные товары.

Метод vm.load() обновляется, чтобы добавить токен, если он доступен. Обработчик ответа теперь объединяет результаты в массив. Это означает, что вторая страница результатов добавляется после первой страницы. Google Maps API будет возвращать next_page_token любое время, когда есть еще результаты, которые можно загрузить. Если это свойство отсутствует, мы можем предположить, что больше нет элементов для загрузки, и vm.canLoad имеет значение false . Компонент бесконечной прокрутки использует это значение, чтобы определить, когда прекратить загрузку большего количества элементов.

Последнее изменение — добавление $scope.$broadcast('scroll.infiniteScrollComplete') . Компонент бесконечной прокрутки не знает, когда HTTP-запрос был выполнен или когда он был сохранен, чтобы отключить символ загрузки. Следовательно, компонент прослушивает события для обновления. В этом случае событие scroll.infiniteScrollComplete сообщает компоненту о том, что нужно остановить вращение и продолжить наблюдать за тем, как пользователь прокручивает scroll.infiniteScrollComplete вниз.

Последняя часть — включить это в шаблон. Откройте www / views / place / place.html и добавьте строку между концом компонентов ionList и ionContent .

1
2
3
4
5
</ion-item>
    </ion-list>
    <ion-infinite-scroll on-infinite=»vm.load()» ng-if=»vm.canLoad»></ion-infinite-scroll>
  </ion-content>
</ion-view>

Компонент бесконечной прокрутки теперь включен в вашем шаблоне. Он начинает следить за тем, когда компонент виден, что также срабатывает при загрузке, поскольку тогда не видно ни одного места, а компонент бесконечной прокрутки виден. Он вызывает метод, объявленный в on-infinite один раз, когда он становится видимым (здесь это vm.load() ) и ожидает, пока не будет vm.load() событие завершения прокрутки.

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

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

Это завершает просмотр мест. Оглядываясь назад, мы видим, что 12 шаблонов HTML включены в шаблон и содержат около 20 строк JavaScript в контроллере.

Мы рассмотрели ряд компонентов, которые вы часто будете использовать в своих приложениях Ionic.

  • Ионные компоненты JavaScript используются в качестве элементов HTML и могут работать согласованно.
  • Ionic имеет ionNavView и ionNavBar для поддержки скоординированной навигации с различными видами.
  • Компоненты ionList и ionItem позволяют легко создавать списки, удобные для мобильных устройств.
  • Компонент ionInfiniteScroll автоматически инициирует вызов для загрузки дополнительных элементов и добавления их в список.

В следующем руководстве будут рассмотрены некоторые полезные сервисы, которые предоставляет Ionic, такие как индикаторы загрузки и всплывающие окна.

Если вы уже знакомы с платформой Ionic, то вы можете рассмотреть возможность участия в конкурсе Envato Most Wanted для ионных шаблонов . Как? Создайте уникальный шаблон Ionic и отправьте его в Envato Market до 27 апреля 2016 года.

Пять лучших шаблонов получают 1000 долларов. Заинтересованы? Читайте больше на сайте конкурса для получения подробной информации о требованиях и правилах конкурса.