В этой серии из двух частей вы узнаете, как создать свое самое первое приложение для Ionic 2. Теперь, когда вы настроили свою среду разработки и узнали о рабочем процессе разработки в Ionic 2, пришло время запачкать руки, написав код приложения.
Если вы еще этого не сделали, следуйте первому посту, чтобы настроить среду разработки и запустить проект .
Во второй части будут рассмотрены вещи, которые необходимо знать, когда речь заходит о кодировании приложений в Ionic 2. Вы узнаете, как создавать страницы для приложения, как получать пользовательский ввод и как использовать плагины для доступа к собственным функциям. Когда вы закончите, вы запустите приложение на устройстве или в эмуляторе. Но прежде чем вы это сделаете, давайте немного поговорим о том, что вы будете создавать.
Что вы будете создавать
В этом уроке вы создадите приложение для обмена фотографиями. Основной поток должен быть следующим:
- Пользователь открывает приложение и входит в систему. Они будут перенаправлены на страницу для выбора изображения для обмена.
- Пользователь нажимает на кнопку «Выбрать изображение» . Появляется средство выбора изображений, и пользователь выбирает одно изображение. Это изображение будет затем предварительно просмотрено.
- Пользователь вводит подпись и нажимает кнопку « Поделиться изображением» , чтобы передать изображение в приложение Instagram.
Из этого туториала вы узнаете, как запустить приложение на устройстве Android, но Cordova (платформа, на которой работает Ionic) является кроссплатформенной. Ionic 2 имеет встроенные темы для Android, iOS и Windows, поэтому можно легко создать версию вашего приложения для этих устройств.
Вот как будет выглядеть приложение:
Настройка проекта
Если вы следовали предыдущему руководству, то у вас уже есть настроенная среда разработки Ionic 2 и ваш проект снят с работы. Для создания дерева папок проекта и подготовки к развертыванию на Android мы использовали следующие команды интерфейса командной строки Ionic 2:
1
2
|
ionic start photoSharer blank —v2 —id com.tutsplus.photosharer
ionic platform add android
|
Мы также установили пару полезных плагинов:
1
2
|
ionic plugin add https://github.com/Telerik-Verified-Plugins/ImagePicker
ionic plugin add cordova-instagram-plugin
|
Кодирование домашней страницы
В остальной части учебника вы будете в основном работать внутри папки src , поэтому каждый раз, когда вы видите путь к файлу, предполагается, что папка src является корневой. (Если вы хотите освежить в памяти пути, созданные с помощью начального шаблона Ionic, посмотрите предыдущий учебник .)
Внутри каталога src находятся четыре папки:
- app : здесь определяется код всего приложения. Если вам нужно запустить определенный код при запуске приложения, или вы хотите обновить глобальный CSS, то это то место, куда можно пойти.
- Ресурсы : это то место, куда идут ресурсы, такие как изображения, используемые в качестве контента для приложения.
- страницы : это где код для отдельных страниц. Каждая страница имеет свою собственную папку, и внутри каждой папки находятся три файла, которые определяют шаблон (HTML), стиль (CSS) и сценарий (TypeScript) для страницы.
- Темы : сюда вы можете перейти, если хотите изменить стандартную тему Ionic 2.
Шаблон домашней страницы
По умолчанию пустой начальный шаблон Ionic уже поставляется с домашней страницей. Так что все, что вам нужно сделать, это отредактировать его, чтобы показать содержимое, которое вы хотите. Откройте файл pages / home / home.html и очистите его текущее содержимое. Добавьте следующее в верхней части страницы:
1
2
3
4
5
6
7
|
<ion-header>
<ion-navbar>
<ion-title>
Login
</ion-title>
</ion-navbar>
</ion-header>
|
Код выше является образцом для заголовка приложения. Компонент <ion-navbar>
служит навигационной панелью инструментов. Он будет автоматически отображать кнопку возврата, когда вы уходите со страницы по умолчанию. <ion-title>
устанавливает заголовок навигационной панели.
Далее идет фактическое содержание страницы. Вы можете определить это внутри компонента <ion-content>
. Заполнение по умолчанию можно применить, указав опцию padding
. Внутри этого контейнера создайте новый список, который содержит поля ввода для ввода имени пользователя и пароля. Создание списка, содержащего поля редактирования, является стандартной практикой в Ionic — оно позволяет аккуратно укладывать каждое поле друг на друга. Ниже списка находится кнопка для входа.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
<ion-content padding>
<ion-list>
<ion-item>
<ion-label>Username</ion-label>
<ion-input type=»text» [value]=»username» [(ngModel)]=»username»></ion-input>
</ion-item>
<ion-item>
<ion-label>Password</ion-label>
<ion-input type=»password» [value]=»password» [(ngModel)]=»password»></ion-input>
</ion-item>
</ion-list>
<div padding>
<button ion-button full (click)=’login();’>Login</button>
</div>
</ion-content>
|
Давайте взглянем на код для ввода текста и нажатия кнопки. В Ionic вы можете определить поля ввода текста, используя компонент <ion-input>
. Чтобы привязать текстовое поле к свойству класса, определенному в вашем скрипте страницы, используйте [(ngModel)]
. Тогда назначенное ему значение является именем свойства класса.
Чтобы установить двустороннюю привязку данных, вы можете установить для [value]
то же имя свойства, которое используется для [(ngModel)]
. Это позволяет обновить значение текстового поля, изменив значение модели из скрипта страницы. Позже вы увидите, как определить свойство класса внутри скрипта страницы.
1
|
<ion-input type=»text» [value]=»username» [(ngModel)]=»username»></ion-input>
|
Чтобы определить кнопки, используйте стандартный элемент button
в HTML. Если вам интересно, почему это не <ion-button>
, это из-за доступности. Кнопки являются ключевым компонентом интерфейса, поэтому команда Ionic решила придерживаться стандартных кнопок HTML, чтобы сделать их доступными. Вместо этого добавляется директива об ion-button
кнопках для обеспечения дополнительной функциональности.
Чтобы добавить обработчик кликов, вы используете директиву (click)
со значением, определяющим функцию (определенную в вашем скрипте страницы), которая будет выполняться при возникновении события click.
1
|
<button ion-button full (click)=’login();’>Login</button>
|
Скрипт домашней страницы
Откройте файл pages / home / home.ts , очистите все его содержимое и добавьте следующее:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
import { Component } from ‘@angular/core’;
import { NavController, AlertController } from ‘ionic-angular’;
//import { PickerPage } from ‘../../pages/picker/picker’;
@Component({
templateUrl: ‘home.html’
})
export class HomePage {
username: string;
password: string;
readonly APP_USERNAME: string = ‘me’;
readonly APP_PASSWORD: string = ‘secret’;
constructor(public navCtrl: NavController, public alertCtrl: AlertController) {
}
login() {
let alert = this.alertCtrl.create({
title: ‘Login Failed’,
subTitle: ‘The username or password you entered is incorrect.’,
buttons: [‘OK’]
});
if (this.username == this.APP_USERNAME && this.password == this.APP_PASSWORD) {
this.navCtrl.push(PickerPage);
} else {
alert.present();
}
this.username = »;
this.password = »;
}
}
|
Разбивая вышеприведенный код, мы сначала импортируем класс компонента Angular, в котором уже содержатся все директивы Ionic.
1
|
import { Component } from ‘@angular/core’;
|
Далее мы импортируем контроллеры для навигации и оповещений из ionic-angular
пакета. Это где все контроллеры Ionic включены.
1
|
import { NavController, AlertController } from ‘ionic-angular’;
|
После этого мы импортируем PickerPage
. Вы создадите его позже, поэтому оставьте его закомментированным. Не забудьте удалить комментарий, как только вы будете готовы к его загрузке.
1
|
//import { PickerPage } from ‘../../pages/picker/picker’;
|
После импорта используйте декоратор @Component
чтобы указать шаблон HTML, который будет использоваться сценарием:
1
2
3
|
@Component({
templateUrl: ‘home.html’
})
|
Теперь мы можем определить класс для скрипта нашей домашней страницы. Мы хотим экспортировать этот класс, чтобы его можно было импортировать из других файлов в приложении.
1
2
3
|
export class HomePage {
…
}
|
Сделайте NavController
и AlertController
доступными по всему классу, определив их как параметры в constructor
. Это позволяет вам использовать this.navCtrl
, например, когда вы хотите использовать NavController
для перехода на другую страницу.
1
2
3
|
constructor(public navCtrl: NavController, public alertCtrl: AlertController) {
}
|
Теперь мы готовы определить свойства нашего контроллера, на которые можно ссылаться из шаблона. Эти свойства будут содержать текущее значение текстового поля для имени пользователя и пароля:
1
2
|
username: string;
password: string;
|
Для простоты мы будем использовать жестко закодированные значения для имени пользователя и пароля. Но для реальных приложений вы обычно делаете запрос к серверу для аутентификации пользователя.
1
2
|
readonly APP_USERNAME: string = ‘me’;
readonly APP_PASSWORD: string = ‘secret’;
|
Внутри функции login()
создайте оповещение, когда пользователь вводит неправильное имя пользователя или пароль:
1
2
3
4
5
|
let alert = this.alertCtrl.create({
title: ‘Login Failed’,
subTitle: ‘The username or password you entered is incorrect.’,
buttons: [‘OK’]
});
|
Если учетные данные неверны, покажите предупреждение:
1
|
alert.present();
|
Если имя пользователя и пароль, NavController
пользователем, соответствуют жестко NavController
значениям, используйте NavController
чтобы NavController
страницу NavController
в стек навигации. Независимо от того, какую страницу вы вставляете в стек навигации, она становится текущей, а всплывающая страница эффективно переходит на предыдущую страницу. Так работает навигация в Ionic 2.
1
|
this.navCtrl.push(PickerPage);
|
Страница выбора
Далее вам нужно создать страницу выбора. Как вы уже знаете, стандарт заключается в создании отдельной папки для каждой страницы, и в каждой папке будет три файла. К счастью, Ionic CLI также поставляется с командой, которая позволяет нам создавать новые страницы:
1
|
ionic g page pickerPage
|
Это использует команду generate
, которая создаст папку страницы с этими тремя файлами внутри. Лучше всего то, что каждый файл уже содержит некоторый шаблонный код, с которого вы можете начать.
Шаблон страницы выбора
Как только это будет сделано, откройте файл pages / picker / picker.html и замените шаблон кода следующим:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
<ion-header>
<ion-navbar>
<ion-title>Pick Image</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<div padding>
<button ion-button full (click)=’pickImage();’>Pick Image</button>
</div>
<ion-card text-center>
<img [src]=»picked_image» />
</ion-card>
<div class=»form-container» [hidden]=»!has_picked_image»>
<ion-list>
<ion-item>
<ion-label stacked>Caption</ion-label>
<ion-input type=»text» [value]=»caption» [(ngModel)]=»caption»></ion-input>
</ion-item>
</ion-list>
<div padding>
<button ion-button full color=»secondary» (click)=’shareImage();’>Share Image</button>
</div>
</div>
</ion-content>
|
Ни один из этого кода не является действительно незнакомым, за исключением hidden
директивы и использования компонента <ion-card>
.
hidden
директива позволяет вам скрывать элемент на основе определенного значения, определенного в вашем скрипте страницы. Так что, если has_picked_image
имеет значение true
, только тогда этот div
будет виден.
1
2
3
|
<div class=»form-container» [hidden]=»!has_picked_image»>
…
</div>
|
Компонент <ion-card>
используется для создания карт . Карты являются отличным способом отображения изображений внутри приложений.
Стиль страницы выбора
Откройте файл pages / picker / picker.scss и добавьте следующее:
1
2
3
|
.form-container {
padding-top: 20px;
}
|
Picker Page Script
Откройте файл pages / picker / picker.ts и добавьте следующее:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
import { Component } from ‘@angular/core’;
import { ImagePicker, Instagram } from ‘ionic-native’;
@Component({
templateUrl: ‘picker.html’
})
export class PickerPage {
picked_image: string;
has_picked_image: boolean = false;
caption: string;
readonly DEFAULT_IMAGE: string = ‘http://placehold.it/500×500’;
constructor() {
this.picked_image = this.DEFAULT_IMAGE;
}
pickImage() {
var options = {
maximumImagesCount: 1,
width: 500,
height: 500,
quality: 50,
outputType: 1
};
ImagePicker.getPictures(options).then((results) => {
this.picked_image = ‘data:image/jpeg;base64,’ + results[0];
this.has_picked_image = true;
}, (err: any) => {
console.log(err);
this.has_picked_image = false;
});
}
shareImage() {
Instagram.share(this.picked_image, this.caption)
.then(() => {
this.picked_image = this.DEFAULT_IMAGE;
this.has_picked_image = false;
})
.catch((error: any) => {
console.error(error);
});
}
}
|
Я сломаю это немного. Сначала мы импортируем плагины, которые вы установили ранее. Обратите внимание, что все плагины установлены в одном пакете ( ionic-native
). Это действительно хорошо, потому что вместо того, чтобы импортировать каждый плагин в отдельной строке, вы можете просто сделать это в одной строке.
1
|
import { ImagePicker, Instagram } from ‘ionic-native’;
|
Далее мы объявляем свойства класса:
1
2
3
4
|
picked_image: string;
has_picked_image: boolean = false;
caption: string;
readonly DEFAULT_IMAGE: string = ‘http://placehold.it/500×500’;
|
Когда нажата кнопка «Выбрать изображение» , определите параметры средства выбора изображения. Эти параметры довольно понятны, но я добавил несколько комментариев, чтобы уточнить, что делает каждый из них.
1
2
3
4
5
6
7
8
|
let options = {
maximumImagesCount: 1, // the maximum number of images that the user can pick
width: 500, // the maximum width in which the image will be in once it is picked
height: 500, // the maximum height in which the image will be in once it is picked
quality: 50, // the quality of the photo.
outputType: 1 // what format the results will be in once the user has picked an image.
// 0 is for file URIs while 1 is for data URIs.
};
|
Указание width
и height
не обязательно означает, что полученное изображение будет использовать именно эти ширину и высоту. Это означает, что Ionic будет использовать эти размеры в качестве максимальной ширины или высоты таким образом, чтобы соотношение сторон сохранялось.
Мы используем URI данных в качестве типа вывода, потому что плагин Instagram принимает только URI данных. Это означает, что вам также необходимо отрегулировать ширину, высоту и качество до минимума, потому что URI данных могут быть очень длинными, если качество высокое — все изображение кодируется в строке URI! Это может привести к сбою приложения, поэтому всегда рекомендуется придерживаться изображений низкого качества и меньшего размера при работе с URI данных.
Затем используйте плагин Image Picker для запуска экрана выбора изображения. Поскольку мы ожидаем только одно изображение, мы можем просто получить доступ к первому элементу в массиве результатов. Мы также должны добавить префикс для URI данных.
1
2
3
4
5
6
7
|
ImagePicker.getPictures(options).then((results) => {
this.picked_image = ‘data:image/jpeg;base64,’ + results[0];
this.has_picked_image = true;
}, (err: any) => {
console.log(err);
this.has_picked_image = false;
});
|
Наконец, когда нажимается кнопка « Поделиться изображением» , метод share
предоставляемый плагином Instagram, запускает экран обмена в приложении Instagram. Это будет иметь предварительно заполненное изображение.
Однако заголовок не будет скопирован. Приложение Instagram отключило предварительно заполненные подписи, поэтому поле заголовка будет пустым после открытия приложения Instagram. В качестве обходного пути плагин Instagram вместо этого копирует заголовок в буфер обмена. Это означает, что пользователь может просто вставить его в текстовое поле заголовка в приложении Instagram.
1
2
3
4
5
6
7
8
|
Instagram.share(this.picked_image, this.caption)
.then(() => {
this.picked_image = this.DEFAULT_IMAGE;
this.has_picked_image = false;
})
.catch((error: any) => {
console.error(error);
});
|
Собираем все вместе
Последний шаг — открыть файл app / app.module.ts . Это корневой модуль приложения, в котором вы определяете все страницы и поставщиков (например, обработчик ошибок Ionic по умолчанию), которые вы будете использовать в приложении.
Убедитесь, что все созданные вами страницы определены, в противном случае вы получите ошибку при переходе на страницу, которая не была определена. По умолчанию HomePage
уже определен здесь, поэтому вам просто нужно добавить PickerPage
. Просто импортируйте его в начало файла, а затем добавьте его в массиве declarations
и entryComponents
. Обратите внимание, что MyApp
не является страницей; это компонент, который служит пустой оболочкой для загружаемых страниц.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
import { NgModule, ErrorHandler } from ‘@angular/core’;
import { IonicApp, IonicModule, IonicErrorHandler } from ‘ionic-angular’;
import { MyApp } from ‘./app.component’;
import { HomePage } from ‘../pages/home/home’;
import { PickerPage } from ‘../pages/picker/picker’;
@NgModule({
declarations: [
MyApp,
HomePage,
PickerPage
],
imports: [
IonicModule.forRoot(MyApp)
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
HomePage,
PickerPage
],
providers: [{provide: ErrorHandler, useClass: IonicErrorHandler}]
})
export class AppModule {}
|
Если вы откроете файл app / app.components.ts , вы увидите следующее:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
import { Component } from ‘@angular/core’;
import { Platform } from ‘ionic-angular’;
import { StatusBar, Splashscreen } from ‘ionic-native’;
import { HomePage } from ‘../pages/home/home’;
@Component({
templateUrl: ‘app.html’
})
export class MyApp {
rootPage = HomePage;
constructor(platform: Platform) {
platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
StatusBar.styleDefault();
Splashscreen.hide();
});
}
}
|
Здесь вы можете определить корневую страницу — страницу, которую пользователь увидит, когда откроет приложение. В этом случае HomePage
является корневой страницей. Это также идеально подходит для выполнения кода инициализации, поскольку код здесь выполняется только один раз, когда пользователь запускает приложение. При инициализации чего-либо (например, запрашивая разрешение на включение Bluetooth) вы всегда будете ждать, пока не platform.ready()
событие platform.ready()
. Только после того, как это событие сработало, вы можете быть уверены, что нативные функции готовы к вызову.
Запуск приложения
Теперь вы готовы запустить приложение на мобильном устройстве или эмуляторе. Вы можете сделать это, выполнив следующую команду:
1
|
ionic run android
|
Убедитесь, что у вас есть устройство, подключенное к вашему компьютеру, или что у вас есть запущенный экземпляр эмулятора, когда вы выполняете команду выше. Если это все еще не работает, проверьте, что вы включили отладку USB на вашем устройстве и запустите adb devices
. Это заставит ваш компьютер подключиться к вашему устройству. Просто согласитесь на подсказку на вашем устройстве, как только вы увидите запрос аутентификации.
Если вы хотите получить копию файла APK, чтобы поделиться им с другом, вы можете сгенерировать ее, выполнив следующее:
1
|
ionic build android
|
Это создаст файл android-debug.apk в папке platform / android / build / output / apk .
Вывод
Это оно! В этом уроке вы создали свое самое первое приложение для Ionic 2. Это простое приложение, и вы могли бы даже легко найти его. Но вы узнали, как настроить среду для разработки приложений Ionic 2, и вы узнали некоторые базовые концепции, которые можно применять при разработке приложений в будущем. К ним относятся получение текущего значения из текстового поля, реагирование на события щелчка, связывание изображений и использование плагинов для доступа к собственным функциям. Так что погладьте себя по спине! Вы хорошо поработали, добравшись до этого.
А пока посмотрите другие наши учебники по Ionic 2!
Если вы хотите получить подробное и практическое введение в среду Ionic 2, попробуйте наш курс Начало работы с Ionic 2
В этом курсе Реджи Доусон расскажет вам все об Ionic Framework и покажет, как создать мобильное приложение с нуля. Попутно вы узнаете о библиотеке компонентов Ionic, о программировании статически типизированного JavaScript с помощью TypeScript и об интеграции приложения Ionic 2 с API-интерфейсом мультимедиа.