Angular vs Angular 2: ключові відмінності

Ми в команді Web Development компанії Itransition вже маємо гарний досвід розробки на Angular 2 і хочемо поділитися ним.

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

Варто починати новий проект на Angular 2?
Однозначно – так! І ось чому:

  • Це грамотно і ретельно спроектований, високопродуктивний фреймворк;
  • З більш низьким порогом входження в порівнянні з першою версією;
  • З хорошою документацією з великою кількістю практичних прикладів.
Початок нового проекту
Нарешті ковток свіжого повітря, повна свобода, можна почати все з чистого аркуша. Гарненько опрацювати архітектуру, структуру даних, компоненти, різні абстракції, скласти якийсь словник термінів додатки і так далі. Щоб все було красиво.

Свобода дій
Але з першою версією Angular не все так просто. Потрібно щоб все придумане лягало на реалії фреймворку, його модулі і сервіси строго певного типу. Не можна просто так взяти і акуратно створити певний клас чи компонент, який буде робити щось важливе. Потрібно вирішити, чим цей компонент буде з точки зору фреймворку? Яким типом сервісу: «value», «constant» чи все ж «factory»? А може бути сервіс типу «service»? Адже він створює об'єкт з оператором new, начебто це те, що потрібно. А раптом сінглтона буде недостатньо? І ці питання виникають практично завжди, працюючи з Angular, в подібних ситуаціях, і немає на них однозначної відповіді.

Відсутність подібного роду обмежень з боку фреймворку, на мій погляд, сильний перевагою Angular 2. Можна використовувати будь-яку зручну модульну систему, як завгодно називати і підключати довільний код.

Генератор коду
Далі для початку роботи над проектом необхідно:

  • створити файлову структуру програми,
  • налагодити роботу з шаблонами,
  • налагодити роботу зі стилями, препроцесором,
  • налаштувати збірку для розробки, налагодження, продакшену,
  • налаштувати процес тестування,
  • ...
З другою версією фреймворку ми отримуємо інструмент командного рядка, з яким можна генерувати програми, модулі, компоненти, директиви, сервіси, фільтри (pipe – нове їх назва), запускати тести, перевірку коду і т. д. І для виконання описаного вище необхідно виконати одну команду:

ng new app-name

Буде створена вся необхідна інфраструктура в кращому на даний момент виконанні. Відразу можна приступати до роботи. Нічого зайвого.

Команда може приймати додаткові аргументи. Наприклад, якщо планується використовувати CSS препроцесор Stylus:

ng new app-name --style=styl

Буде автоматично налаштована компіляція і складання стилів з урахуванням обраного препроцесора.

TypeScript
Згенерований код програми буде використовувати TypeScript, який лякає багатьох, швидше за все просто з-за помилкових уявлень про нього. Насправді це той же JavaScript (ECMAScript 6), але з деякими приємними і корисними примочками:

  • інтерфейси,
  • типізація,
  • перерахування (Enum),
  • модифікатори (public, private, static),
  • декоратори (@).
Все це дозволяє писати більш стабільний і красивий код, позбавляє від потреби повсюдно використовувати кепський JSDoc.

Почавши використовувати TypeScript, хочеться писати тільки на ньому, і вже не розумієш, як можна було бути таким грішним – не використовувати його раніше?

Компоненти
У Angular 2 немає контролерів, тільки компоненти. Створити новий можна таким чином:

ng generate component playground/player

Ця команда створить директорію player в playground з мінімально необхідним кодом компоненти:

  1. файл реалізації,
  2. файл шаблону,
  3. файл стилів з розширенням використовуваного CSS препроцесора,
  4. файл юніт-тестів.
Жодних копипастов — джерела зла і помилок! Згенерований код реалізації компоненту буде такий:

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

@Component({
selector: 'app-player',
templateUrl: './player.component.html',
styleUrls: ['./player.component.styl']
})
export class PlayerComponent implements OnInit {
constructor() {}

ngOnInit() {}
}

@ + Component тут – і є приклад декоратора. У кінцевому рахунку, це проста функція, яка отримує в якості аргументу конструктор, визначений нижче, і змінює його з урахуванням описаної конфігурації, в даному випадку це:

  1. selector – визначає, як буде називатися елемент компонента в шаблонах додатки (<app-player></app-player>),
  2. templateUrl – шлях до файлу шаблону поточного компонента,
  3. styleUrls – масив шляхів до файлів стилів компонента.
Крім перерахованих параметрів існують і інші, які дозволяють писати код шаблона і стилі в цьому ж файлі, конфігурувати інкапсуляцію стилів цього компонента і т. д.

Two-way binding
Ключова фішка Angular — two-way binding. Як вона реалізована в Angular 2?

<app-player [(position)]="playerPosition"></app-player>

Така запис в шаблоні передасть значення властивості playerPosition поточного компонента і буде змінювати його при зміні властивості position всередині компонента player. Це і є two-way binding.

Але чому саме така задоволена дивна запис?

У Angular 2 з'явився новий синтаксис, який дозволяє передавати значення властивостей дочірнім компонентів (one-way binding). Використовує він квадратні дужки:

<app-player [position]="playerPosition"></app-player>

І можна підписуватися на події, що виникають в дочірніх компонентах. Використовуються круглі дужки:

<app-player (positionChange)="onPositionChange($event)"></app-player>

Такий запис означає, що в компоненті player є властивість positionChange, яке є екземпляром класу EventEmitter. І коли в компоненті player викликається this.positionChange.emit(newValue), виконується код onPositionChange($event), зазначений у шаблоні. $event буде містити значення newValue.

Власне, так в Angular 2 і реалізується two-way binding:

  1. передача вихідного значення властивості,
  2. підписка на подію з назвою «назва властивості всередині дочірнього компонента» + «Change»,
  3. зміна властивості в батьківському компоненті при появі події.
А запис [(position)]=«playerPosition» є лише синтаксичним цукром, яка робить все описане автоматично і економить час на будівництво будинку, посадку дерева і вирощування сина.

Завдяки цій реалізації в Angular 2 немає вотчерів, які раніше були джерел багатьох проблем з продуктивністю. Тепер все більш природно.

Принципи SOLID
У нашій команді ми активно використовуємо принципи SOLID, які роблять підтримку та подальшу розробку програми більш ефективним і приємним процесом.

Angular 2 вирішує безліч проблем, пов'язаних з високим рівнем зв'язаності коду, нової потужної реалізацією Dependency Injection та можливістю абстрагуватися від реалізацій різних взаємозв'язаних компонентів, використовуючи інтерфейси (TypeScript).

Наприклад, можна написати таку конструкцію:

class SomeComponent {
constructor(public someService: SomeService) {}
}

І при створенні екземпляра цього компонента автоматично буде створений екземпляр сервісу SomeService і переданий в конструктор SomeComponent. Це дуже сильно знижує рівень зв'язності та дозволяє тестувати їх окремо один від одного.

Так само, запис public someService (TypeScript) робить цей сервіс доступним усередині екземпляра класу за допомогою ключового слова this (this.someService).

Валідація форм
Валідація на основі шаблонів, яка була раніше, залишилася, але з'явилася нова додаткова реалізація. Її конфігурація повністю відбувається в JavaScript, що дозволяє формувати набір правил динамічно, створювати реюзабельные валідатори і повністю керувати процесом, в тому числі фільтрувати користувальницький введення.

Приклад реалізації форми введення нового пароля з перевіркою його складності і підтвердженням:

let passwordControl = new FormControl(", [
Validators.required,
CustomValidators.complexPassword,
]);

let passwordConfirmControl = new FormControl(", [
Validators.required,
]);

this.formGroup = new FormGroup({
password: passwordControl,
passwordConfirm: passwordConfirmControl,
}, CustomValidators.match(passwordControl, passwordConfirmControl));

Валідатор (Validators.required і подібні) – проста функція, в яку передається значення і яка повертає null або об'єкт з описом помилки.

В шаблоні форми потрібно вказати formGroup:

<form [formGroup]="formGroup">

Полів вводу потрібно вказати відповідні назви контролів formGroup:

< input type="password" formControlName="password">
<input type="password" formControlName="passwordConfirm">

І все. Валидна форма, всі помилки і стану можна отримувати через об'єкт formGroup, який буде оновлюватися при кожному взаємодії користувача з нею.

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

{
path: 'profile',
loadChildren: 'app/profile/prodile.module#ProfileModule'
}

Обробка всіх запитів, що починаються з /profile (/profile/photo, /profile/orders, /profile/orders/:id), буде передана ProfileModule, який буде завантажений раз при першій необхідності.

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

На мій погляд, це з-за того, що:

  • максимально використовуються можливості JavaScript,
  • багато речей реалізовані більш логічним і очікуваним чином,
  • якість підказок і авто-завершення на вищому рівні (завдяки TypeScript),
  • є командний рядок для генерації всього необхідного,
  • хороша документація.
Але це не говорить про легкості його засвоєння людиною не знає JavaScript.

Висновок
Ще багато можна написати про нову версію фреймворку, порівняти основні сервіси, розібратися, як відбувається робота з синхронними операціями (Zone.js), згадати про реактивному програмуванні (Rx.js) і так далі. Але це вже буде не стаття, а ціла книга.

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

QuickStart

Успіхів!
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.