Що нового в Angular 8.0?
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
на додаток до існуючих markAsDirty
, markAsTouched
, markAsPending
і т.д. AbstractControl
є батьківським класом FormGroup
, FormControl
, FormArray
, тому метод доступний на всіх реактивних форм юридичних осіб.
Як 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
тепер пропонує доступ до hostname
, port
і protocol
, а новий getState()
метод дозволяє отримати history.state
. MockPlatformLocation
Також доступна для полегшення тестування. Все це дійсно корисно, якщо ви використовуєте ngUpgrade
, інакше вам, мабуть, це не знадобиться.
Service worker
Стратегія реєстрації
Реєстрація Service worker має новий варіант, який дозволяє уточнити, коли має відбутися реєстрація. Раніше Service worker очікував на стабільність програми для реєстрації, щоб уникнути уповільнення запуску програми. Але якщо ви починали повторювану асинхронну задачу (наприклад, процес опитування) на початковому завантаженні програми, то програма ніколи не була стабільною, оскільки Angular вважає програму стабільною, якщо відсутня завдання. Так що Service worker ніколи не реєструвався, і вам довелося вручну обійти його. За допомогою нової registrationStrategy
опції ви можете дозволити Angular впоратися з цим. Можливі кілька значень:
registerWhenStable
, за замовчуванням, як описано вищеregisterImmediately
, який не чекає, поки програма стане стабільною, і відразу реєструє Service workerregisterDelay:$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?“