From 9f65b787d07be8ed2c694ba33cf687d8463725dc Mon Sep 17 00:00:00 2001 From: Kara Erickson Date: Tue, 7 Jan 2020 16:48:13 -0800 Subject: [PATCH] docs: deprecate undecorated base classes that use Angular features (#34668) PR Close #34668 --- aio/content/guide/deprecations.md | 58 +++++++++++++++++++ .../guide/migration-undecorated-classes.md | 2 +- aio/content/guide/updating-to-version-9.md | 3 +- 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/aio/content/guide/deprecations.md b/aio/content/guide/deprecations.md index 788d3e6062..c898463d07 100644 --- a/aio/content/guide/deprecations.md +++ b/aio/content/guide/deprecations.md @@ -42,6 +42,7 @@ v9 - v12 | `@angular/core` | [`RenderComponentType`](#core) | v10 | | `@angular/core` | [`ViewEncapsulation.Native`](#core) | v10 | | `@angular/core` | [`ModuleWithProviders` without a generic](#moduleWithProviders) | v10 | +| `@angular/core` | [Undecorated base classes that use Angular features](#undecorated-base-classes) | v10 | | `@angular/forms` | [`ngModel` with reactive forms](#ngmodel-reactive) | v10 | | `@angular/router` | [`preserveQueryParams`](#router) | v10 | | `@angular/upgrade` | [`@angular/upgrade`](#upgrade) | v10 | @@ -87,6 +88,7 @@ Tip: In the [API reference section](api) of this doc site, deprecated APIs are i | [`entryComponents`](api/core/NgModule#entryComponents) | none | v9 | See [`entryComponents`](#entryComponents) | | [`ANALYZE_FOR_ENTRY_COMPONENTS`](api/core/ANALYZE_FOR_ENTRY_COMPONENTS) | none | v9 | See [`ANALYZE_FOR_ENTRY_COMPONENTS`](#entryComponents) | | `ModuleWithProviders` without a generic | `ModuleWithProviders` with a generic | v9 | See [`ModuleWithProviders` section](#moduleWithProviders) | +| Undecorated base classes that use Angular features | Base classes with `@Directive()` decorator that use Angular features | v9 | See [undecorated base classes section](#undecorated-base-classes) | @@ -302,6 +304,62 @@ However, in practice, Angular simply ignores two-way bindings to template variab ``` +{@a undecorated-base-classes} +### Undecorated base classes using Angular features + +As of version 9, it's deprecated to have an undecorated base class that: + +- uses Angular features +- is extended by a directive or component + +Angular lifecycle hooks or any of the following Angular field decorators are considered Angular features: + +- `@Input()` +- `@Output()` +- `@HostBinding()` +- `@HostListener()` +- `@ViewChild()` / `@ViewChildren()` +- `@ContentChild()` / `@ContentChildren()` + +For example, the following case is deprecated because the base class uses `@Input()` and does not have a class-level decorator: + +```ts +class Base { + @Input() + foo: string; +} + +@Directive(...) +class Dir extends Base { + ngOnChanges(): void { + // notified when bindings to [foo] are updated + } +} +``` + +In a future version of Angular, this code will start to throw an error. +To fix this example, add a selectorless `@Directive()` decorator to the base class: + +```ts +@Directive() +class Base { + @Input() + foo: string; +} + +@Directive(...) +class Dir extends Base { + ngOnChanges(): void { + // notified when bindings to [foo] are updated + } +} +``` + +In version 9, the CLI has an automated migration that will update your code for you when `ng update` is run. +See [the dedicated migration guide](guide/migration-undecorated-classes) for more information about the change and more examples. + + + {@a binding-to-innertext} ### Binding to `innerText` in `platform-server` diff --git a/aio/content/guide/migration-undecorated-classes.md b/aio/content/guide/migration-undecorated-classes.md index 52ca4476d5..38af381cfa 100644 --- a/aio/content/guide/migration-undecorated-classes.md +++ b/aio/content/guide/migration-undecorated-classes.md @@ -1,4 +1,4 @@ -# Undecorated Classes Migration +# Missing `@Directive()`/`@Component()` Decorator Migration ## What does this migration do? diff --git a/aio/content/guide/updating-to-version-9.md b/aio/content/guide/updating-to-version-9.md index 984d08c950..ec89e93b79 100644 --- a/aio/content/guide/updating-to-version-9.md +++ b/aio/content/guide/updating-to-version-9.md @@ -37,6 +37,7 @@ See our [template type-checking guide](guide/template-typecheck) for more inform | [`entryComponents`](api/core/NgModule#entryComponents) | none | See [`entryComponents`](guide/deprecations#entryComponents) | | [`ANALYZE_FOR_ENTRY_COMPONENTS`](api/core/ANALYZE_FOR_ENTRY_COMPONENTS) | none | See [`ANALYZE_FOR_ENTRY_COMPONENTS`](guide/deprecations#entryComponents) | | `ModuleWithProviders` without a generic | `ModuleWithProviders` with a generic | See [`ModuleWithProviders` section](guide/deprecations#moduleWithProviders) | +| Undecorated base classes that use Angular features | Base classes with `@Directive()` decorator that use Angular features | See [undecorated base classes section](guide/deprecations#undecorated-base-classes) | | `esm5` and `fesm5` distribution in `@angular/*` npm packages | `esm2015` and `fesm2015` entrypoints | See [`esm5` and `fesm5`](guide/deprecations#esm5-fesm5) | | [`TestBed.get`](api/core/testing/TestBed#get) | [`TestBed.inject`](api/core/testing/TestBed#inject) | Same behavior, but type safe. | @@ -81,7 +82,7 @@ In Version 9, Angular Ivy is the default rendering engine. If you haven't heard Read about the migrations the CLI handles for you automatically: - [Migrating from `Renderer` to `Renderer2`](guide/migration-renderer) -- [Migrating undecorated classes](guide/migration-undecorated-classes) +- [Migrating missing `@Directive()`/`@Component()` decorators](guide/migration-undecorated-classes) - [Migrating missing `@Injectable()` decorators and incomplete provider definitions](guide/migration-injectable) - [Migrating dynamic queries](guide/migration-dynamic-flag) - [Migrating to the new `$localize` i18n support](guide/migration-localize)