Як створити свій перший додаток Ionic 4 за допомогою дзвінків API

Отже, ви щойно помітили, що вийшов Ionic 4, і ви нарешті хочете розпочати розробку крос-платформних додатків? Ну, сьогодні ваш день! Ми пройдемо створення вашої першої програми Ionic 4 із HTTP-дзвінками до бази даних Open Movie!

Незалежно від того, чи повністю ви новачок в Ionic, чи використовували попередні версії, ми розглянемо всі основи. Ми розглянемо, як налаштувати новий додаток , маршрутизацію та навіть виклики API для відображення асинхронних даних у нашому додатку.

Якщо ви хочете вивчити йонічну ще швидше, ви також можете перевірити мою Йонічну академію, створену для таких же розробників, як розробники!

Готові ? Іди !

Налаштування нашої програми Ionic 4

Якщо ви новачок в Ionic, вам потрібно переконатися, що у вас встановлений Node Package Manager. Якщо ви працювали з іншими веб-технологіями до того, як шанси виявилися досить хорошими, ви вже отримали все необхідне.

Якщо ви також раніше не використовували Ionic, вам потрібно встановити його через npm. Після встановлення ви нарешті готові створити свій проект Ionic 4!

Щоб створити порожній проект, ви можете використовувати Ionic CLI, щоб ми отримали новий проект Ionic 4 з підтримкою Angular ( ви також можете використовувати React або Vue, краща підтримка з'явиться пізніше цього року ).

Після створення проекту ми CD в папку. Ми використовуємо CLI, який використовує Angular CLI під капотом, щоб створити нові сторінки для нашого додатку, які ми хочемо відображати.

# Install Ionic if you haven't before npm install -g ionic # Create a blank new Ionic 4 app with Angular support ionic start movieApp blank --type=angular cd movieApp # Use the CLI to generate some pages and a service ionic g page pages/movies ionic g page pages/movieDetails ionic g service services/movie

Тепер ви можете безпосередньо відкрити свій додаток, запустивши в своєму проекті таку команду:

ionic serve

Це відкриє браузер із попереднім переглядом вашої програми, який автоматично перезавантажиться, коли ви щось зміните у своєму проекті.

Говорячи про проект, у нас тут купа файлів і папок, давайте подивимось, що все це означає. Ми зосередимося на папці src нашого додатку, оскільки наразі нам не потрібно турбуватися про решту.

Додаток

Це папка, куди ми внесемо всі зміни коду, які підуть далі в цьому посібнику. Він уже містить домашню папку, яка в основному є сторінкою, яку ми створили раніше. Мені подобається мати всі сторінки у власній папці сторінок, щоб ви могли і зараз видалити домашню папку.

У сторінках папка містить фактичні думки / сторінки нашого додатка, що означає елемент , ми побачимо на екрані. Зараз у нас вже є 2 сторінки, і кожна сторінка, яку ви створюєте за допомогою CLI, містить 4 файли:

  • * .module.ts: Модуль Angular для сторінки. В основному кожна сторінка - це власний модуль (пов’язаний з архітектурою Angular) із імпортом та стилем
  • * .page.html: HTML- розмітка сторінки
  • * .page.scss: Стиль для конкретної сторінки (докладніше про глобальний стиль пізніше)
  • * .page.spec.ts: Автоматично доданий файл тестування для вашої сторінки. Добре, якщо ви хочете налаштувати автоматизовані модульні тести
  • * .page.ts: контролер сторінки, що містить код Javascript, який керує функціональністю

У папці " Служби" міститься наша раніше створена послуга - це стосується структурування вашого додатка відповідно до найкращих практик та розділення проблем між видом та фактичними даними вашого додатка. Служба подбає про обробку викликів API і просто поверне дані в наш подання пізніше!

Активи

Ця папка містить усі зображення, шрифти або будь-яке інше, що потрібно для вашого додатка пізніше.

Середовища

Час від часу у вашому проекті може бути середовище розробки, постановки та виробництва з різними серверами, на які орієнтована ваша програма. Папка середовища допомагає налаштувати інформацію для різних середовищ. Пізніше ми можемо створити наш додаток Ionic з прапором командного рядка, і він автоматично приймає правильні значення. Дуже зручно!

Тема

Ця папка містить лише змінні.scss, які містять заздалегідь визначену інформацію про кольори від Ionic. Ми завжди можемо змінити цей файл і навіть скористатися таким інструментом, як генератор кольорів іонних, щоб створити власну ароматизовану версію цього файлу!

Поза папкою ми також маємо файл global.scss. Тут ми можемо написати кілька SCSS, які будуть застосовані до нашого додатку в усьому світі. Ми також можемо визначити це лише для однієї сторінки у власних файлах стилів.

Інші файли

Найрелевантнішим з інших файлів може бути index.html, оскільки, як і на будь-якому іншому веб-сайті, цей файл позначає точку входу в наш додаток! Поки що нам не потрібно щось тут міняти, тож давайте зараз почнемо входити у фактичний код.

Необхідна маршрутизація та HTTP-дзвінки

З Ionic 4 ми переходимо від власної концепції маршрутизації до стандартного кутового маршрутизатора. На початку розмітка може виглядати дещо складніше, але насправді це має цілком сенс.

Для всіх з’єднань у вашому додатку ви заздалегідь налаштовуєте інформацію про маршрутизацію - так само, як ви орієнтуєтесь на веб-сайті!

У нашому додатку нам потрібні 2 маршрути:

  • / фільми - Перейдіть на нашу першу сторінку, яка повинна відображати список фільмів
  • / movies /: id - Ми хочемо мати можливість показувати деталі одного фільму, тому ми додаємо param : id до маршруту, який ми можемо динамічно вирішувати

Нам також потрібно підключити відповідну сторінку ( більш конкретно : модуль сторінки) до маршруту, щоб Angular знав, як вирішити конкретний маршрут. Ми надаємо цю інформацію за допомогою loadChildren, який фактично отримує лише рядок до шляху модуля .

Це означає, що ми насправді не імпортуємо ще один модуль, отже, сторінки використовують ледаче завантаження. Це означає, що вони будуть завантажені лише після того, як ми там перейдемо!

Щоб налаштувати нашу інформацію про маршрутизацію, відкрийте наш app / app-routing.module.ts і змініть її на:

import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; const routes: Routes = [ { path: '', redirectTo: 'movies', pathMatch: 'full' }, { path: 'movies', loadChildren: './pages/movies/movies.module#MoviesPageModule' }, { path: 'movies/:id', loadChildren: './pages/movie-details/movie-details.module#MovieDetailsPageModule' } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }

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

Тепер додаток завантажить нашу сторінку фільмів як першу сторінку, чудово! Ви також повинні помітити цю зміну у своєму запущеному ionic serveекземплярі.

Порада. Якщо ви хочете краще зрозуміти, як ваш додаток буде виглядати на реальному пристрої, ви також можете запустити ionic labзамість обслуговування, але вам доведеться встановити пакет заздалегідь:

# Install the Lab Package npm i @ionic/lab # Run your app with device preview and platform styles ionic lab

Цей пакет раніше входив у комплект із кожним новим додатком, але зараз його потрібно встановити для Ionic 4.

/ Підказка Кінець

Нам також потрібно застосувати ще одну зміну до нашого додатку, оскільки ми хочемо робити дзвінки HTTP. Тому нам потрібно імпортувати інший модуль Angular для надсилання цих запитів.

Це робиться так само, як і з Ionic 3. Нам просто потрібно додати HttpClientModuleфайл до нашого основного файлу модуля та додати його до масиву імпорту, як це всередині нашого app / app.module.ts :

import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { RouteReuseStrategy } from '@angular/router'; import { IonicModule, IonicRouteStrategy } from '@ionic/angular'; import { SplashScreen } from '@ionic-native/splash-screen/ngx'; import { StatusBar } from '@ionic-native/status-bar/ngx'; import { AppComponent } from './app.component'; import { AppRoutingModule } from './app-routing.module'; import { HttpClientModule } from '@angular/common/http'; @NgModule({ declarations: [AppComponent], entryComponents: [], imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule, HttpClientModule], providers: [ StatusBar, SplashScreen, { provide: RouteReuseStrategy, useClass: IonicRouteStrategy } ], bootstrap: [AppComponent] }) export class AppModule {}

Перш ніж ми заглибимося в більше Ionic 4 коду, спочатку ми повинні налаштувати службу, яка керує нашим додатком і обробляє всі HTTP-запити, які ми пізніше хочемо викликати.

Надання запитів HTTP

Послуга така ж, як і в попередніх версіях, постачальник і може бути введена в наш контролер для виклику її функцій.

Для того, щоб використовувати базу даних Open Movie, вам потрібно запросити ключ API та вставити його в наш сервіс - процес безкоштовний, тому продовжуйте прямо зараз.

Завдяки API ми тепер можемо шукати рядки та отримувати результати у вигляді фільмів, серій чи навіть ігор. Крім того, ми можемо отримати детальну інформацію про один конкретний об’єкт цих результатів, тому ідеальний варіант використання для нашого першого додатку Ionic 4!

Нашому сервісу потрібні лише 2 функції:

  • searchData(): Ця функція здійснює пошук результатів за певним заголовком та типом пошуку - перелік, який ми визначили заздалегідь для представлення типів, які ми можемо передати API за допомогою TypeScript!
  • getDetails(): Ця функція повертає детальну інформацію щодо одного конкретного елемента, яка буде використана на нашій сторінці деталей

Обидві функції повернуть значення Observable, подібне до обіцянки на стероїдах. Несерйозно, це як потік подій, на які ми можемо підписатися . Пояснення цієї концепції зайняло б інший пост. Поки що давайте використовуватимемо його та мати на увазі, що обидві наші функції є асинхронними - вони повернуть дані API не відразу.

Тепер змініть свої послуги / movie.service.ts на:

import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; // Typescript custom enum for search types (optional) export enum SearchType { all = '', movie = 'movie', series = 'series', episode = 'episode' } @Injectable({ providedIn: 'root' }) export class MovieService { url = '//www.omdbapi.com/'; apiKey = ''; // <-- Enter your own key here! /** * Constructor of the Service with Dependency Injection * @param http The standard Angular HttpClient to make requests */ constructor(private http: HttpClient) { } /** * Get data from the OmdbApi * map the result to return only the results that we need * * @param {string} title Search Term * @param {SearchType} type movie, series, episode or empty * @returns Observable with the search results */ searchData(title: string, type: SearchType): Observable { return this.http.get(`${this.url}?s=${encodeURI(title)}&type=${type}&apikey=${this.apiKey}`).pipe( map(results => results['Search']) ); } /** * Get the detailed information for an ID using the "i" parameter * * @param {string} id imdbID to retrieve information * @returns Observable with detailed information */ getDetails(id) { return this.http.get(`${this.url}?i=${id}&plot=full&apikey=${this.apiKey}`); } }

Я також додав деяку документацію до функцій - за допомогою такого інструменту, як Compodoc, ви тепер можете створити гарну документацію!

Добре, тепер ми нарешті готові до ще коду Ionic 4!

Пошук фільмів

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

Тож зараз нам потрібно застосувати логіку, щоб подати пошуковий термін і ввести в нашу службу та отримати результати. Тому ми вводимо службу через наш конструктор, щоб вона була доступна для класу.

В іншій функції, яку ми називаємо searchChanged(), тепер ми просто викликаємо відповідну функцію нашого сервісу і встановлюємо результат на локальну змінну b> results. Пізніше наш погляд буде обробляти дані, що надходять з API, і відображатиме їх за допомогою цієї змінної.

Ми також зберігаємо ще 2 змінні для searchTerm і вводимо всередину нашого класу, який ми передаємо службі. Ми також зв’яжемося з ними, щоб ми могли їх змінити.

Тепер продовжуйте з кодом вашого контролера всередині сторінок / movies / movies.page.ts :

import { MovieService, SearchType } from './../../services/movie.service'; import { Component, OnInit } from '@angular/core'; import { Observable } from 'rxjs'; @Component({ selector: 'app-movies', templateUrl: './movies.page.html', styleUrls: ['./movies.page.scss'], }) export class MoviesPage implements OnInit { results: Observable; searchTerm: string = ''; type: SearchType = SearchType.all; /** * Constructor of our first page * @param movieService The movie Service to get data */ constructor(private movieService: MovieService) { } ngOnInit() { } searchChanged() { // Call our service function which returns an Observable this.results = this.movieService.searchData(this.searchTerm, this.type); } }

Тепер вигляд, який дуже схожий на код Ionic 3, лише деякі елементи змінили свої назви та властивості. Для всіх, хто новачок в Ionic загалом: Ласкаво просимо до ваших перших іонних компонентів !

Сторінку можна розділити на 3 області: верхній, зміст, нижній колонтитул. У нашому випадку ми не хочемо нижнього колонтитула, тому ми визначаємо лише область заголовка із заголовком та вмістом із нашими фактичними елементами для пошуку.

Перший елемент, який впливає на пошук, ion-searchbar- це простий ввід, який ви бачили у багатьох програмах раніше для пошуку терміна.

Ми завжди хочемо викликати нашу функцію пошуку, коли змінюється тип або searchTerm. Ми можемо зробити це, зловивши подію (ionChange) деяких наших елементів.

Нижче ми отримали спадне меню з опціями та відповідним значенням для різних типів, які ми могли б повернути API.

Ви також повинні були помітити синтаксис [(ngModel)], за допомогою якого обидва елементи підключаються до властивостей нашого контролера. Якщо одна сторона зміниться, інша також автоматично отримає нове значення (також відоме як двостороння прив'язка даних ).

Отож ми здійснили пошук на місці, а тепер додаємо ще один список з елементами під нашими попередніми компонентами.

Для списку ми використовуємо ітерацію над нашою змінною результатів. Оскільки ця змінна є Observable (пам’ятайте про реалізацію в нашому сервісі), нам потрібно додати кутову трубу “| async ”до нього. Представлення підписується на Observable і обробляє зміни відповідно.

Ми також додаємо маршрутизацію безпосередньо до цього елемента за допомогою [routerLink]. Ми будуємо шлях, який ми хочемо відкрити, натиснувши на елемент. Ми використовуємо властивість imdbID елемента, щоб пізніше можна було визначити інформацію на нашій сторінці деталей.

Окрім цього, ми створюємо розмітку для одного елемента, використовуючи плакат, який є зображенням, заголовком, роком і, нарешті, також класною піктограмою в і залежно від типу товару. Так, ці класні піктограми вже додаються до вашого додатка і називаються Ionicons!

З огляду на все це, змініть ваші сторінки / movies / movies.page.html на:

  My Movie Search      Select Searchtype  All Movie Series Episode      

{{ item.Title }}

{{ item.Year }}

На даний момент ви вже зможете шукати певний термін у своєму додатку та отримувати список результатів - це вже великий виграш !

If you are coming form Ionic 3 you might have also noted another new property called slot so here’s some info on that:

Ionic 4 components are built using Stencil (yeah, they actually created that tool as well!) so they are standard web components — you could import them basically everywhere on the web! These components also use the Shadow DOM API and are basically living outside of the scope of your regular DOM elements.

That means also standard styling will sometimes not affect these components like it was possible in previous versions!

In order to get information into these components, we can inject certain parts of HTML into their slots that are defined on these elements. You can see how their implementation looks like on the example of the ion-item we used here.

Presenting Detailed Information

Ok enough of background information, let’s put some more work into the details page of our app. We have implemented a route and we also created a button that passed an ID with that route so the details page will be open, but we need to get access to the ID!

With previous Ionic versions we could easily pass whole objects to new pages, this is now not a best practice anymore. Instead, we pass only small chunks of information (like an ID) with the URL. Otherwise, you would end up with a huge JSON stringified term inside the URL. This isn’t really something we want to have.

To get access to this ID field (that we already defined inside our routing in the beginning) we can use the ActivatedRoute and its properties.

So after we extract the ID from the params we can make another call to our service (that we injected through the constructor again) and get the detailed information for whatever ID we got.

Nothing really new so let’s add the following code to our pages/movie-details/movie-details.page.ts:

import { MovieService } from './../../services/movie.service'; import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; @Component({ selector: 'app-movie-details', templateUrl: './movie-details.page.html', styleUrls: ['./movie-details.page.scss'], }) export class MovieDetailsPage implements OnInit { information = null; /** * Constructor of our details page * @param activatedRoute Information about the route we are on * @param movieService The movie Service to get data */ constructor(private activatedRoute: ActivatedRoute, private movieService: MovieService) { } ngOnInit() { // Get the ID that was passed with the URL let id = this.activatedRoute.snapshot.paramMap.get('id'); // Get the information from the API this.movieService.getDetails(id).subscribe(result => { this.information = result; }); } openWebsite() { window.open(this.information.Website, '_blank'); } }

We also added another function to open a website using the window object and the information from the data of the API that we stored in the local information variable.

Now we just need to create a view based on the JSON information of the API. It always helps to log() out the info you got so you see keys that you can use to display some values.

In our case, we use the Ionic card component and add the image and some items with information and more icons (did I say I really like the Ionicons?).

We also added a button below that card that will be displayed if the result information contains the website key. We just have to add our function to the (click) event of the button in order to hook everything up!

On another note, we also have to add an ion-back-button to the header of that page in order to get a nice little back arrow to our previous movie list page. This was automatically done in v3 but needs to implemented manually as of v4!

Now finish your details view by changing your pages/movie-details/movie-details.page.html to:

     {{ information?.Genre }}       {{ information.Title }}   {{ information.Year }}     {{ information.Plot }}   {{ information.imdbRating }}    {{ information.Director }}    {{ information.Actors }}    Open Website    

If you now take a look at your browser you might notice that the image looks waaaay to big as its taking all the space available. Let’s change this through some good old CSS so open your pages/movie-details/movie-details.page.scss and insert:

.info-img { max-height: 30vh; object-fit: contain; padding: 10px; }

Now our results look a lot more appealing.

We can search, select a movie type, dive into a search result and have a fully functional Ionic 4 app with HTTP calls finished!

Conclusion

While it was a straight forward experience to build our first Ionic 4 app there are so many things we haven’t talked enough about.

UI patterns like Tabs and side menu, CSS variables, responsive layout and PWA to just name a few on the side of Ionic and Angular.

And we haven’t even touched the Cordova side of things to actually build this app into a real native mobile app!

If you want to learn how to develop Ionic 4 apps as fast as possible and get them to the iOS & Android app stores quickly you can join the Ionic Academy today and enjoy expert screencasts, a library of quick wins and a community to support you on your journey!

And of course, I (Simon) am also present inside to answer all your questions all the time

You can also find a video version of this guide below!

Originally published at ionicacademy.com on January 24, 2019.