Що нового в Angular 8.0?

Angular 8

Angular 8.0 має трохи більше мій код, ніж інші випуски 😊.

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

TypeScript 3.4

Angular 8.0 тепер підтримує TypeScript 3.4 і навіть вимагає його, тому вам потрібно оновити.

Ви можете перевірити, що надає TypeScript 3.3 і TypeScript 3.4 у блозі Microsoft.

Ivy

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

TL; DR: Ivy – новий компілятор / час виконання Angular. В майбутньому він дозволить створити дуже цікаві функції, але наразі він зосереджен на не порушенні існуючих програм.

Angular 8.0 – це перший реліз, який офіційно пропонує перейти до входу в Ivy. Зараз немає реальних переваг для цього, але ви можете дати йому спробу побачити, чи нічого не руйнуеться у вашій програмі. Тому що в певний момент, ймовірно, в v9, Ivy буде за замовчуванням. Отже, команда Angular сподівається, що громада очікує на перемикання та надасть зворотній зв’язок, і що ми розглянемо всі інші питання до v9.

Ми спробували його на декількох наших програмах і вже потрапили до декількох регресій, тому ми настійно рекомендуємо не використовувати його сліпо у виробництві.

Якщо ви відчуваєте пригоди, ви можете додати "enableIvy": trueу свій angularCompilerOptionsі перезапустити програму: вона тепер використовує Ivy! Перегляньте статтю та офіційний довідник для отримання додаткової інформації .

Підтримка Bazel

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

Форми

markallastouched

AbstractControlКлас пропонує новий метод markAllAsTouched на додаток до існуючих markAsDirtymarkAsTouchedmarkAsPendingі т.д. AbstractControlє батьківським класом FormGroupFormControlFormArray, тому метод доступний на всіх реактивних форм юридичних осіб.

Як markAsTouched, цей новий метод позначає контроль як touched і його нащадків.

form.markAllAsTouched();

FormArray.clear

FormArrayКлас тепер також пропонує clearспосіб, щоб швидко видалити всі елементи управління , які він містить. Раніше вам довелося прокрутити елементи керування, щоб видалити їх по одному.

// `users` is initialized with 2 users
const users = fb.array([user1, user2]);
users.clear();
// users is now empty

Router

Lazy-loading з синтаксисом import()

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

Тепер це кращий спосіб оголосити маршрут відвантаження, а строкова форма застаріла. Цей синтаксис подібний до стандарту ECMAScript, і Ivy підтримує лише це.

Таким чином, ви можете змінити свої loadChildrenдекларації з:

loadChildren: './admin/admin.module#AdminModule'

до:

loadChildren: () => import('./races/races.module').then(m => m.RacesModule)

Схема, запропонована CLI, автоматично мігрує ваші декларації для вас, тому це має бути безболісним, якщо ви запускаєте ng update @angular/cli. Перегляньте нашу статтю про Angular CLI 8.0, щоб дізнатися більше про це.

Location

Щоб допомогти мігрувати з AngularJS, до служб визначення місцезнаходження в Angular було додано купу речей.

PlatformLocationтепер пропонує доступ до hostnameport і protocol, а новий getState()метод дозволяє отримати history.stateMockPlatformLocationТакож доступна для полегшення тестування. Все це дійсно корисно, якщо ви використовуєте ngUpgrade, інакше вам, мабуть, це не знадобиться.

Service worker

Стратегія реєстрації

Реєстрація Service worker має новий варіант, який дозволяє уточнити, коли має відбутися реєстрація. Раніше Service worker очікував на стабільність програми для реєстрації, щоб уникнути уповільнення запуску програми. Але якщо ви починали повторювану асинхронну задачу (наприклад, процес опитування) на початковому завантаженні програми, то програма ніколи не була стабільною, оскільки Angular вважає програму стабільною, якщо відсутня завдання. Так що Service worker ніколи не реєструвався, і вам довелося вручну обійти його. За допомогою нової registrationStrategyопції ви можете дозволити Angular впоратися з цим. Можливі кілька значень:

  • registerWhenStable, за замовчуванням, як описано вище
  • registerImmediately, який не чекає, поки програма стане стабільною, і відразу реєструє Service worker
  • registerDelay:$TIMEOUTз $TIMEOUTчислом мілісекунд очікування перед реєстрацією
  • функція, що повертає Observable, для визначення користувацької стратегії. Потім Service worker реєструватиметься, коли об’єкт спостереження випускає своє перше значення.

Наприклад, якщо ви бажаєте зареєструвати Service worker через 2 секунди:

providers: [
  ServiceWorkerModule.register('/ngsw-worker.js', {
    enabled: environment.production,
    registrationStrategy: 'registerDelay:2000'
  }),
  // ...
]

Обхід Service worker

Тепер можна також обходити Service worker для окремого запиту, додавши ngsw-bypassзаголовок.

this.http.get('api/users', { headers: { 'ngsw-bypass': true } });

Кілька додатків на субдоменах

Раніше було неможливо мати декілька додатків, що використовувалися @angular/service-workerна різних підпрограмах одного і того ж домену, тому що коженService worker перезапише кеші інших… Це тепер виправлено!

Notable і breaking зміни

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

Просто запустіть ng update @angular/core і схеми оновлять ваш код. Що роблять ці схеми? Давай дізнаємось!

Час запитів

В ViewChildі ContentChildдекоратори повинні тепер мати новий варіант називається static. Дозвольте мені пояснити, чому з дуже простим прикладом ViewChild:

<div *ngIf="true">
  <div #dynamicDiv>dynamic</div>
</div>

Давайте зробимо цей елемент в нашому компоненті і занотуємо його в гаки життєвого циклу ngOnInit і ngAfterViewInit:

@ViewChild('dynamicDiv') dynamicDiv: ElementRef<HTMLDivElement>;

ngOnInit() {
  console.log('init dynamic', this.dynamicDiv); // undefined
}

ngAfterViewInit() {
  console.log('after view init dynamic', this.dynamicDiv); // div
}

Має сенс, коли AfterViewInit викликається, коли виконується ініціалізація шаблону.

Але насправді, якщо запитуваний елемент є статичним (не загорнутий в ngIfані ngFor), то він доступний ngOnInitтакож:

<h1 #staticDiv>static</h1>

дає:

@ViewChild('staticDiv') staticDiv: ElementRef<HTMLDivElement>;

ngOnInit() {
  console.log('init static', this.staticDiv); // div
}

ngAfterViewInit() {
  console.log('after view init static', this.staticDiv); // div
}

Це не було задокументовано або рекомендовано, але саме так він працює.

Хоча з Ivy, поведінка змінюється більш послідовно:

ngOnInit() {
  console.log('init static', this.staticDiv); // undefined (changed)
}

ngAfterViewInit() {
  console.log('after view init static', this.staticDiv); // div
}

Введено новий static прапор, щоб не порушувати існуючі програми, тому, якщо ви хочете зберегти стару поведінку, навіть коли ви перейдете на Ivy, ви можете написати:

@ViewChild('static', { static: true }) static: ElementRef<HTMLDivElement>;

і поведінка буде такою ж, як і поточна (елемент також доступний ngOnInit).

Зверніть увагу, що якщо ви додасте static: true на динамічний елемент (загорнутий у стан або цикл), то він не буде доступний ngOnInit ні в, ні в ngAfterViewInit!

static: false буде як Ivy поводиться за замовчуванням.

Щоб не порушувати існуючі програми та полегшити міграцію, команда Angular написала схему, яка автоматично аналізує вашу програму та додає staticпрапор. Він навіть пропонує дві стратегії:

  • один на основі ваших шаблонів, який переконається, що ваша програма працює (тому вона має тенденцію позначати запити як статичні, навіть якщо вони не є). Ви впевнені, що він працює, але він піддає вам проблеми, якщо ви перегортаєте ваш статичний елемент у стан або цикл.
  • один, заснований на використанні запиту, який є більш схильним до помилок (оскільки схемою це важче зрозуміти), але не позначить запити як статичні, якщо вони не потрібні. Так що більшість запитів буде мати static: false, що буде за замовчуванням у Ivy.

Перша стратегія використовується за замовчуванням при запуску, ng updateоскільки вона є найбезпечнішою, але ви можете спробувати використати стратегію використання NG_STATIC_QUERY_USAGE_STRATEGY=true ng update.

Додаткову інформацію можна отримати в офіційному довіднику .

Так виглядає міграція (з помилкою в одному компоненті):

------ Static Query Migration ------
With Angular version 8, developers need to
explicitly specify the timing of ViewChild and
ContentChild queries. Read more about this here:
https://v8.angular.io/guide/static-query-migration

Some queries could not be migrated automatically. Please go
those manually and apply the appropriate timing.
For more info on how to choose a flag, please see:
https://v8.angular.io/guide/static-query-migration
⮑   home/home.component.ts@43:3: undefined

Зауважимо, що це стосується тільки ViewChildі ContentChild, а не ViewChildrenі ContentChildren (яке буде працювати так само в Ivy і View Engine).

Перепризначення змінної шаблону

Наразі з інструментом “Перегляд” виконуються такі дії:

<button
  *ngFor="let option of options"
  (click)="option = 'newButtonText'">{{ option }}</button>

працює.

У Ivy, це не буде так: більше не буде можливо перепризначити значення змінної шаблону (тут option). Щоб підготувати комутатор до Ivy, схема аналізує ваші шаблони під час оновлення до Angular 8.0 і попереджає вас, якщо це так.

Потім її потрібно вручну виправити:

<button
  *ngFor="let option of options; index as index"
  (click)="options[index] = 'newButtonText'">{{ option }}</button>

ДОКУМЕНТ

DOCUMENTМаркер переміщається від @angular/platform-browserв @angular/common. Ви можете вручну змінити його у вашій програмі, але надана схема буде подбати про неї.

Застарілий пакет webworker

@angular/platform-webworkerПакет включено працює вашому Angular додатоку в Web Worker. Оскільки це виявилося складнішим, ніж очікувалося (для побудови програми, SEO…), і не дуже добре, продукти були застарілими і будуть видалені в майбутньому.

Заборонений пакет HTTP видалено

@angular/httpбуло видалено з 8.0, після заміни @angular/common/httpв 4.3 і офіційно застаріло в 5.0 , 18 місяців тому. Ви, напевно, вже перенесли на @angular/common/http, але якщо ви цього не зробили, тепер вам доведеться: надана схема буде лише видалити залежність від вашого package.json.

Ви також можете знайти всі застарілі API у офіційному довіднику знецінення .

Це все для Angular 8.0! Ви можете переглянути наші інші статті про Ivy , випуск CLI 8.0 або нову підтримку Bazel .

Переклад статті “What’s new in Angular 8.0?