Знайомимось з Angular 2, створюючи додаток для пошуку зображень на Giphy

19 хв. читання

Для тих, хто прийшов зі світу Angular 1, я буду проводити порівняння. Тим не менш, вам не обов'язково знати Angular 1. Але ви повинні бути знайомі з JavaScript, щоб зрозуміти, про що тут йде мова.

Цей туторіал навчить вас, як користуватися Angular CLI для розробки Angular 2 додатку для пошуку Giphy гіфок, використовуючи API сервісу.

Основи

Ви всі чули новини; Angular 2 є/буде наступним найкращим інструментом у світі веб- та мобільної розробки (з фреймворком Ionic).

Ви все ще можете сказати:

Так, звичайно, але я чув, що React / Ember / ... набагато краще

Я відповім на це питання так само, як я відповів на конференції кілька місяців тому:

Будь ласка, припиніть цей аналітичний параліч. Оберіть фреймворк (будь-який з них), який використовується вашим ком'юніті, попрацюйте з ним і подивіться, чи багато ви зможете з ним зробити. Всі ці розмови про X повільніше або Y краще не мають ніякого сенсу, поки ви самі не спробуєте та не оберете найкращий варіант.

Пристебніть ремені безпеки, візьміть чашку кави і поїхали!

Демо-додаток

Як було сказано раніше, ми будемо розробляти додаток для пошуку (і представлення) гіфок з сайту Giphy, використовуючи їх API.

Ви можете спробувати додаток тут, і ви також можете форкнути сирцевий код на GitHub.

Передумови

Впевніться, що наступні інструменти розробки вже встановлені на вашому ком'ютері:

  • Node.js - покроковий гайд для Windows та Mac
  • Git - безкоштовний інтерактивний туторіал тут
  • Bower - комплексний туторіал тут
  • Gulp - туторіал для початку роботи з ним тут

Мігруєте з Angular 1?

Отже, ви продивилися кілька рядків нового Angular 2.0, і у вас реакція, схожа на:

Angular {full-post-img}

Довіртесь мені; Я розумію ваш біль. Я досить комфортно себе почував, працюючи з Angular 1. Проте, тепер я вам скажу те, що ви вже мабуть чули:

Angular 2.0 набагато краще, ніж його попередник.

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

До речі, є швидкий, простий метод переміщення додатків з Angular 1. Якщо ви хочете більш детально дізнатися про те, як перемістити додаток на Angular 2, то почніть з цього.

Angular CLI

Розробка додатку на Angular 2 з нуля (принаймні в даний момент) потребує дуже багато роботи з встановлення та налаштування параметрів.

У Ember є одна велика перевага; інструмент, який називається ember-cli, який bootstrap"ить додатки і допомагає з деякими загальними тасками у проекті.

Звичайно, ми мали Yeoman і його Angular generators, але вони не стали широко відомими, і це безумовно не був такий самий інструмент, як у Ember. Доказом того, що Ember CLI попереду, є те, що сторінка Github по Angular-CLI каже:

Прототип CLI для Angular 2 додатків базується на основі проекту ember-cli.

Тепер до Angular CLI. Незважаючи на те, що цей проект ще в бета-версії, ми можемо використовувати його, щоб:

  • Створювати скаффолдингові додатки з правильною структурою директорій та тестами (!), за допомогою однієї простої команди (ng new)
  • Сформувати компоненти, маршрути, послуги і пайпи (CLI також створить прості тест-shell"и (!) до всього цього)
  • Легко запустити ваш додаток (ng serve)
  • Розгорнути додаток на GitHub Pages (ng github-pages:deploy)
  • Запустит модульні тести (!)
  • Запустити офіційний Angular 2 лінтер (ng lint)
  • ...

Давайте перейдемо до інсталяції Angular CLI.

Інсталяція angular-cli

Запустіть:

npm install -g angular-cli

Ви можете переконатися, що інсталяція пройшла добре, запустивши команду:

ng --help

і отримати купу повідомлень про допомогу з різнимм командами у angular cli.

Просто для довідки (в разі, якщо ви будете слідувати цьому туторіалу і щось буде не схоже на те, що виводиться в мене), моя версія (ng --version) на момент написання цієї статті angular-cli: 1.0.0-beta.9.

Починаємо розробку нового додатку з angular cli

Ми будемо називати наш додаток GiphySearch. Отже, давайте почнемо новий додаток з angular-cli:

ng new GiphySearch

Ви отримаєте вивід, подібний цьому:

# nikola in ~/DEV/Angular2 [13:57:55]
→ ng new GiphySearch
Could not start watchman; falling back to NodeWatcher for file system events.
Visit http://ember-cli.com/user-guide/#watchman for more info.
installing ng2
  create .editorconfig
  create README.md
  create src/app/app.component.css
  create src/app/app.component.html
  create src/app/app.component.spec.ts
  create src/app/app.component.ts
  create src/app/environment.ts
  create src/app/index.ts
  create src/app/shared/index.ts
  create src/favicon.ico
  create src/index.html
  create src/main.ts
  create src/system-config.ts
  create src/tsconfig.json
  create src/typings.d.ts
  create angular-cli-build.js
  create angular-cli.json
  create config/environment.dev.ts
  create config/environment.js
  create config/environment.prod.ts
  create config/karma-test-shim.js
  create config/karma.conf.js
  create config/protractor.conf.js
  create e2e/app.e2e-spec.ts
  create e2e/app.po.ts
  create e2e/tsconfig.json
  create e2e/typings.d.ts
  create .gitignore
  create package.json
  create public/.npmignore
  create tslint.json
  create typings.json
Successfully initialized git.
⠸ Installing packages for tooling via npm
├── es6-shim (ambient)
├── angular-protractor (ambient dev)
├── jasmine (ambient dev)
└── selenium-webdriver (ambient dev)

Installed packages for tooling via npm.

Після того, як ця команда завершить свою роботу, давайте зробимо cd у проект та запустимо його:

cd GiphySearch
ng serve

Ви повинні отримати...

# nikola in ~/DEV/Angular2/GiphySearch on git:master ● [14:05:03]
→ ng serve
Could not start watchman; falling back to NodeWatcher for file system events.
Visit http://ember-cli.com/user-guide/#watchman for more info.
Livereload server on http://localhost:49154
Serving on http://localhost:4200/

Build successful - 889ms.

Slowest Trees                                 | Total               
----------------------------------------------+---------------------
BroccoliTypeScriptCompiler                    | 484ms               
vendor                                        | 332ms               

Slowest Trees (cumulative)                    | Total (avg)         
----------------------------------------------+---------------------
BroccoliTypeScriptCompiler (1)                | 484ms               
vendor (1)                                    | 332ms               

Браузер повинен показати вам рядок app works! коли ви переходите до додатку через http://localhost:4200/.

У разі, якщо вам цікаво щодо "Could not start watchman" вище. Ви можете дізнатися більше тут. Коротше кажучи, посилання розкаже вам про використання brew install watchman, якщо ви на Mac.

Структура папок

Тепер, давайте відкриємо цей проект в будь-якому текстовому редакторі (я використовую Sublime Text 3), і ви побачите щось на зразок цього:

Angular

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

Angular

Що таке TypeScript?

Тепер вам може бути цікаво, що означають всі ці файли .ts?

Це файли TypeScript, і навіть якщо вам не обов'язково використовувати TypeScript з Angular 2, ймовірно, усі на цій Землі так роблять.

Отже, що ж це таке? На своєму сайті вони стверджують, що:

TypeScript - це суперсет JavaScript, який компілюється у чистий JavaScript.

Можливо, ви вже бачили це зображення раніше:

Angular

З нього, ми можемо бачити, що TypeScript містить ES6 (EcmaScript6), який містить ES5 (ECMAScript5), що означає, що TypeScript також містить ES5.

Оскільки більшість браузерів на сьогоднішній день не можуть запустити ES6 або один лише TypeScript, ми використовуємо так званий transpiler, які перетворюють наш TypeScript або ES6 код в ES5 код, який розуміють усі сучасні браузери.

Деякі функції, які має TypeScript:

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

Оголосіть змінну як:

var myVar: string;

Зверніть увагу на те, що ми оголосили тип нашої змінної за допомогою : string.

Крім того, тепер у вас є можливість вказати тип поверненого значення функції:

function myFunc (msg: string): string {
    return 'I like to repeat what you said, therefore: ' + msg;
}

Просто для довідки, ми маємо наступні типи:

  • string
  • number
  • array
  • enum
  • any
  • void

Якщо ви хочете ще погратися з TypeScript (в окремому проекті), то вам треба буде встановити TS, використовуючи наступну команду:

npm install -g typescript

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

Для швидкого прикладу, давайте створимо файл під назвою tsTest.ts і вставимо у нього попередню функцію, з викликом функції, такої як console.log(myFunc('hello'));. Наш файл повинен виглядати наступним чином:

function myFunc (msg: string): string {
    return 'I like to repeat what you said, therefore: ' + msg;
}

console.log(myFunc('hello'));

Потім запустіть цей файл через TypeScript компілятор ось так:

tsc tsTest.ts

Після цього ви повинні побачити файл tsTest.js з вашим файлом tsTest.ts, тепер ви можете запустити його з node:

node tsTest.js

і як вивід, ви отримаєте I like to repeat what you said, therefore: hello.


Додавання контенту

Окей, давайте додамо щось у наш додаток.

Але з чого почати?

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

Таким чином, якщо ми шукаємо рядок app works!, ви знайдете його в файлі app.component.ts (в папці app). Цей файл містить наступне:

import { Component } from '@angular/core';

@Component({
  moduleId: module.id,
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.css']
})
export class AppComponent {
  title = 'app works!';
}

Імпорти

Що означають усі ці @ символи?

Не знаючи нічого, ми можемо побачити, де змінити текст app works!. Отже, давайте змінимо його на Welcome to GiphySearch.

Добре, давайте з'ясуємо, що означає весь цей код:

import { Component } from '@angular/core';

Команда import оголошує, які частини ми будемо імпортувати і використовувати в нашому коді. У нашому випадку, ми імпортуємо Component з модуля @angular/core.

Компоненти

Якби веб-розробка мала свою газету або свій журнал, ви би, ймовірно, побачили заголовки типу:

Директиви застарілі, Компоненти дають надію на майбутнє

Всі на борт з Компонентами

Компоненти: чому ви повинні використовувати їх і чому вони змінять світ.

Коротше кажучи, компоненти - це нові директиви, які, у разі, якщо ви знайомі з Angular 1, є будівельними блоками вашого angular-додатку.

Звичайний компонент:

import { Component } from "@angular/core";

@Component({
  selector: 'awesome',
  template: `
       <div>
          Awesome content right here!
       </div>
    `
})

class Awesome { }

Компонент Декоратор (@Component) додає додаткові дані до класу, який слідує йому (Awesome):

  • selector - каже Angular, який елемент поставити у відповідність
  • template - визначає представлення

Компонент контролер визначається класом Awesome .

Ми зможемо використовувати цей новий тег (awesome) в нашому HTML так: <awesome></awesome>, і коли він з'являється перед користувачем у браузері, він буде у вигляді Awesome content right here!.

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

Незважаючи на те, що є деякі люди, які оголошують шаблон всередині @Component, я намагаюся уникати цього і оголошую HTML шаблон в окремому файлі. angular-cli також віддає перевагу цьому.

Додавання поля вводу та кнопки

Наш базовий додаток повинен мати одне поле вводу та одну кнопку.

Для цього додайте наступний код у файл app.component.html:

<input name="search">

<button>Search</button>

Дії

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

Отже, ось як оголошувати функцію, яка буде обробляти натискання кнопок у Angular 2:

<button (click)="performSearch()">Search</button>

Але тепер, якщо ви натиснете на цю кнопку, ви отримаєте повідомлення про помилку. Це тому, що ми ще ніде на оголосили функцію performSeach.

Давайте зробимо це зараз. У файлі app.component.ts додайте наступне оголошення функції всередині класу AppComponent:

performSearch(): void {
    console.log('button click is working');
}

Таким чином ми оголосили функцію performSearch, яка не приймає ніяких параметрів і нічого (void) не повертає. Замість цього вона просто виводить button click is working у консоль.

Приймаємо запит

Що робити, якщо ми б хотіли ввести у консоль рядок, який хтось ввів у поле введення?

Ну, по-перше, нам потрібно додати новий атрибут в поле input:

<input #searchterm="" name="title">

#searchTerm каже Angular зв'язати вхід input з новою змінною searchTerm.

Потім, ми повинні передати цю змінну функції performSearch так:

<button (click)="performSearch(searchTerm)">Search</button>

І, нарешті, в файлі app.components.ts змініть функцію performSearch наступним чином:

performSearch(searchTerm: HTMLInputElement): void {
    console.log(`User entered: ${searchTerm.value}`);
}

Таким чином, ми додали новий параметр у функцію (searchTerm), яка відноситься до типу HTMLInputElement. І ми використовували зворотні лапки для виведення рядка в console.log. Ви повинні помітити, як ми використовували ${} для виведення змінної всередині лапок. Оскільки searchTerm є об'єктом, ми повинні були отримати його значення шляхом посилання на його value ($ {searchTerm.value}). (!)

Giphy search API

Нарешті, ми підійшли до крутої частини - вилучення даних з сервісу та їх представлення у нашому додатку (в нашому випадку, ми будемо показувати зображення).

Отже, як ми знаходимо цей API? Якщо ви зробите простий пошук в Google на giphy api і відкриєте перше посилання, ви отримаєте документацію по їх API.

Нам потрібен search API. Якщо трохи прокрутити, ви знайдете наступне посилання:

http://api.giphy.com/v1/gifs/search?q=funny+cat&api_key=dc6zaTOxFJmzC

Чудово, тепер ми бачимо, який запит нам потрібно створити, щоб проводити пошук у базі даних Giphy.

Якщо ви відкриєте це посилання в браузері, ви побачите, що повертає сервіс. Щось на зразок:

Angular

У наступному розділі ми розглянемо, як отримати ці дані у нашому додатку.

Запити Angular HTTP

У Angular 2, ми завжди імпортуємо сервіс HTTP з модуля @angular/http. Це робиться наступною командою:

import { HTTP_PROVIDERS } from '@angular/http';

Тепер ми можемо ввести Http в наш компонент.

У файлі app.components.ts додайте наступний код після першого імпорту:

import { Http, Response } from '@angular/http';

Потім оголосіть дві змінні:

link = 'https://web.archive.org/web/20230327104121/http://api.giphy.com/v1/gifs/search?api_key=dc6zaTOxFJmzC&q=';
http: Http;

Після цього додайте конструктор ось так:

constructor(http: Http) {
    this.http = http;
}

І, нарешті, вставте це у функцію performSearch:

var apiLink = this.link + searchTerm.value;

this.http.request(apiLink)
    .subscribe((res: Response) => {
        console.log(res.json());
    });

Просто для довідки, вміст файлу app.component.ts має виглядати так:

import { Component } from '@angular/core';
import { Http, Response } from '@angular/http';

@Component({
    moduleId: module.id,
    selector: 'app-root',
    templateUrl: 'app.component.html',
    styleUrls: ['app.component.css']
})

export class AppComponent {
    title = 'Welcome to GiphySearch';
    link = 'https://web.archive.org/web/20230327104121/http://api.giphy.com/v1/gifs/search?api_key=dc6zaTOxFJmzC&q=';
    http: Http;

    constructor(http: Http) {
        this.http = http;
    }

    performSearch(searchTerm: HTMLInputElement): void {
        var apiLink = this.link + searchTerm.value;

        this.http.request(apiLink)
            .subscribe((res: Response) =>  {
                  console.log(res.json());
            });
    }
};

Якщо ви запустите це зараз, ви отримаєте повідомлення про помилку No provider for Http!. Цю помилку можна виправити, додавши наступний імпорт-рядок у файл main.ts (в папці app):

import { HTTP_PROVIDERS } from '@angular/http';

В кінці того ж файлу, додайте bootstrap(AppComponent, [HTTP_PROVIDERS]);.

Тепер, вміст файлу app.ts має бути:

Angular

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

Але, як ми покажемо ці зображення?

Ми бачимо, що виклик API повертає 25 зображень. Давайте збережемо це в змінній для використання пізніше:

giphies = [];

Давайте також збережемо результати від виклику API у цій змінній:

this.giphies = res.json().data;

Тепер, вміст файлу app.component.ts має бути:

import { Component } from '@angular/core';
import { Http, Response } from '@angular/http';

@Component({
    moduleId: module.id,
    selector: 'app-root',
    templateUrl: 'app.component.html',
    styleUrls: ['app.component.css']
})

export class AppComponent {
    title = 'Welcome to GiphySearch';
    link = 'https://web.archive.org/web/20230327104121/http://api.giphy.com/v1/gifs/search?api_key=dc6zaTOxFJmzC&q=';
    http: Http;
    giphies = [];

    constructor(http: Http) {
        this.http = http;
    }

    performSearch(searchTerm: HTMLInputElement): void {
        var apiLink = this.link + searchTerm.value;

        this.http.request(apiLink)
            .subscribe((res: Response) => {
                  this.giphies = res.json().data;
                  console.log(this.giphies);
            });
    }
};

Все це чудово, але ми не хочемо виводити ці об'єкти у консоль, ми хочемо виводити їх у наш додаток.

Для того, щоб показати зображення, нам потрібно спозиціонувати себе на об'єкті images, а потім original, і, нарешті, на url.

Крім того, ми не хочемо показувати лише одне зображення, ми хочемо показати зразу всі. Для цього використаємо ng-for (версію від Angular 2). Воно тепер виглядає наступним чином:

<img src="{{g.images.original.url}}">

Для довідки, ось повний вигляд app.component.html:

<h1>
  {{title}}
</h1>
        
<input #searchterm="" name="search">
        
<button (click)="performSearch(searchTerm)">Search</button>

<br>

<div>
    <img src="{{g.images.original.url}}">
</div>

Тепер, якщо ми введемо у пошук, наприклад, "смішні котики" ми отримаємо наступне:

Angular

Хоча результат не ідеальний, але наш код робить саме те, що він повинен робити. Якщо ви хочете, щоб усе виглядало краще, то додайте більше CSS у файл app.components.css.

Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 5.8K
Приєднався: 8 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація