parent
02134172dd
commit
de62d8ebdb
|
@ -3,17 +3,12 @@
|
||||||
|
|
||||||
## What does this migration do?
|
## What does this migration do?
|
||||||
|
|
||||||
In Angular version 8, a schematic added `static` flags to all `@ViewChild()`
|
In Angular version 8, a schematic added `static` flags to all `@ViewChild()` and `@ContentChild()` queries.
|
||||||
and `@ContentChild()` queries.
|
|
||||||
This was the first step towards changing the default behavior.
|
This was the first step towards changing the default behavior.
|
||||||
With version 9, the default value
|
With version 9, the default value changes to `static: false` and the flag becomes optional.
|
||||||
changes to `static: false` and the flag becomes optional.
|
|
||||||
|
|
||||||
This schematic scans classes in the compilation and for each
|
This schematic scans classes in the compilation and for each class, checks if the members have a `@ViewChild()` or `@ContentChild()` query with the `static` flag set to `false`.
|
||||||
class, checks if the members have a `@ViewChild()` or
|
If so, the schematic removes the flag, as it now matches the default.
|
||||||
`@ContentChild()` query with the `static` flag set to
|
|
||||||
`false`. If so, the schematic removes the flag, as it
|
|
||||||
now matches the default.
|
|
||||||
|
|
||||||
**Before:**
|
**Before:**
|
||||||
```ts
|
```ts
|
||||||
|
@ -31,48 +26,31 @@ now matches the default.
|
||||||
@ViewChild('bar', {static: true}) bar: ElementRef;
|
@ViewChild('bar', {static: true}) bar: ElementRef;
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that the flag is not supported in `@ViewChildren()`
|
Note that the flag is not supported in `@ViewChildren()` or `@ContentChildren()` queries, so the schematic will not check these properties.
|
||||||
or `@ContentChildren()` queries, so the schematic
|
|
||||||
will not check these properties.
|
|
||||||
|
|
||||||
|
|
||||||
## Why is this migration necessary?
|
## Why is this migration necessary?
|
||||||
|
|
||||||
This schematic performs a code cleanup to remove `static`
|
This schematic performs a code cleanup to remove `static` flags that match the default, as they are no longer necessary.
|
||||||
flags that match the default, as they are no longer
|
Functionally, the code change should be a noop.
|
||||||
necessary. Functionally, the code change should be a noop.
|
|
||||||
|
|
||||||
Before version 9, Angular figured out the static or
|
Before version 9, Angular figured out the static or dynamic nature of a query automatically, based on how the template was written.
|
||||||
dynamic nature of a query automatically, based
|
Looking at templates in this way, however, caused buggy and surprising behavior (see more about that in the [Static Query Migration Guide](guide/static-query-migration#what-does-this-flag-mean)).
|
||||||
on how the template was written. Looking at templates
|
As of version 9, Angular uses dynamic queries (`static: false`) by default, which simplifies queries.
|
||||||
in this way, however, caused buggy and surprising behavior
|
Developers can still explicitly set a query to `static: true` if necessary.
|
||||||
(see more about that in the [Static Query Migration Guide](guide/static-query-migration#what-does-this-flag-mean)).
|
|
||||||
As of version 9, Angular uses dynamic queries
|
|
||||||
(`static: false`) by default, which simplifies
|
|
||||||
queries. Developers can still explicitly set a
|
|
||||||
query to `static: true` if necessary.
|
|
||||||
|
|
||||||
|
|
||||||
<div class=" alert is-helpful">
|
<div class=" alert is-helpful">
|
||||||
|
|
||||||
### What is the difference between static and dynamic queries?
|
### What is the difference between static and dynamic queries?
|
||||||
|
|
||||||
The `static` option for `@ViewChild()` and `@ContentChild()`
|
The `static` option for `@ViewChild()` and `@ContentChild()` queries determines when the query results become available.
|
||||||
queries determines when
|
|
||||||
the query results become available.
|
|
||||||
|
|
||||||
With static queries (`static: true`), the query resolves
|
With static queries (`static: true`), the query resolves once the view has been created, but before change detection runs.
|
||||||
once the view has been created, but before change detection runs.
|
The result, though, will never be updated to reflect changes to your view, such as changes to `ngIf` and `ngFor` blocks.
|
||||||
The result, though, will never be updated to reflect
|
|
||||||
changes to your view, such as
|
|
||||||
changes to `ngIf` and `ngFor` blocks.
|
|
||||||
|
|
||||||
With dynamic queries (`static: false`), the query resolves
|
With dynamic queries (`static: false`), the query resolves after either `ngAfterViewInit()` or `ngAfterContentInit()` for `@ViewChild()` and `@ContentChild()` respectively.
|
||||||
after either `ngAfterViewInit()` or
|
The result will be updated for changes to your view, such as changes to `ngIf` and `ngFor` blocks.
|
||||||
`ngAfterContentInit()` for `@ViewChild()` and `@ContentChild()`
|
|
||||||
respectively. The result will
|
|
||||||
be updated for changes to your view, such as changes to
|
|
||||||
`ngIf` and `ngFor` blocks.
|
|
||||||
|
|
||||||
For more information, see the following entries in the
|
For more information, see the following entries in the
|
||||||
[Static Query Migration Guide](https://angular.io/guide/static-query-migration):
|
[Static Query Migration Guide](https://angular.io/guide/static-query-migration):
|
||||||
|
@ -86,22 +64,19 @@ For more information, see the following entries in the
|
||||||
|
|
||||||
## What does this mean for libraries?
|
## What does this mean for libraries?
|
||||||
|
|
||||||
In order to support applications that are still running
|
In order to support applications that are still running with version 8, the safest option for libraries is to retain the `static` flag to keep the resolution timing consistent.
|
||||||
with version 8, the safest option for libraries is to
|
|
||||||
retain the `static` flag to keep the resolution
|
|
||||||
timing consistent.
|
|
||||||
|
|
||||||
- *Libraries on version 9 with applications running version 8: *
|
- *Libraries on version 9 with applications running version 8: *
|
||||||
|
|
||||||
The schematic won't run on libraries. As long as libraries retain their `static` flags from version 8, they should work with apps on 8.
|
The schematic won't run on libraries.
|
||||||
|
As long as libraries retain their `static` flags from version 8, they should work with apps on 8.
|
||||||
|
|
||||||
- *Libraries on version 8 with applications running version 9: *
|
- *Libraries on version 8 with applications running version 9: *
|
||||||
|
|
||||||
Libraries will have explicit flags defined. The behavior
|
Libraries will have explicit flags defined.
|
||||||
with explicit flags has not changed.
|
The behavior with explicit flags has not changed.
|
||||||
|
|
||||||
|
|
||||||
### What about applications using non-migrated libraries?
|
### What about applications using non-migrated libraries?
|
||||||
|
|
||||||
Because this is a code cleanup that is a noop,
|
Because this is a code cleanup that is a noop, non-migrated libraries will work the same either way.
|
||||||
non-migrated libraries will work the same either way.
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
application but are not decorated.
|
application but are not decorated.
|
||||||
2. The schematic updates providers which follow the `{provide: SomeToken}` pattern
|
2. The schematic updates providers which follow the `{provide: SomeToken}` pattern
|
||||||
to explicitly specify `useValue: undefined`.
|
to explicitly specify `useValue: undefined`.
|
||||||
|
|
||||||
**Example for missing `@Injectable()`**
|
**Example for missing `@Injectable()`**
|
||||||
|
|
||||||
_Before migration:_
|
_Before migration:_
|
||||||
|
@ -29,6 +29,7 @@ export class MyFifthClass {...}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
_After migration:_
|
_After migration:_
|
||||||
```ts
|
```ts
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -47,8 +48,8 @@ with `@Injectable()` because they are never instantiated, but just used as a [DI
|
||||||
|
|
||||||
**Example for provider needing `useValue: undefined`**
|
**Example for provider needing `useValue: undefined`**
|
||||||
|
|
||||||
This example shows a provider following the `{provide: X}` pattern. The provider needs to be
|
This example shows a provider following the `{provide: X}` pattern.
|
||||||
migrated to a more explicit definition where `useValue: undefined` is specified.
|
The provider needs to be migrated to a more explicit definition where `useValue: undefined` is specified.
|
||||||
|
|
||||||
_Before migration_:
|
_Before migration_:
|
||||||
```typescript
|
```typescript
|
||||||
|
@ -61,16 +62,12 @@ _After migration_:
|
||||||
|
|
||||||
### Why is adding `@Injectable()` necessary?
|
### Why is adding `@Injectable()` necessary?
|
||||||
|
|
||||||
In our docs, we've always recommended adding `@Injectable()`
|
In our docs, we've always recommended adding `@Injectable()` decorators to any class that is provided or injected in your application.
|
||||||
decorators to any class that is provided or injected in your application.
|
However, older versions of Angular did allow injection of a class without the decorator in certain cases, such as AOT mode.
|
||||||
However, older versions of Angular did allow injection of a class
|
This means if you accidentally omitted the decorator, your application may have continued to work despite missing `@Injectable()` decorators in some places.
|
||||||
without the decorator in certain cases, such as AOT mode.
|
This is problematic for future versions of Angular.
|
||||||
This means if you accidentally omitted the decorator, your application
|
Eventually, we plan to strictly require the decorator because doing so enables further optimization of both the compiler and the runtime.
|
||||||
may have continued to work despite missing `@Injectable()` decorators in some places.
|
This schematic adds any `@Injectable()` decorators that may be missing to future-proof your app.
|
||||||
This is problematic for future versions of Angular. Eventually, we plan
|
|
||||||
to strictly require the decorator because doing so enables further
|
|
||||||
optimization of both the compiler and the runtime. This schematic
|
|
||||||
adds any `@Injectable()` decorators that may be missing to future-proof your app.
|
|
||||||
|
|
||||||
### Why is adding `useValue: undefined` necessary?
|
### Why is adding `useValue: undefined` necessary?
|
||||||
|
|
||||||
|
@ -83,28 +80,26 @@ Consider the following pattern:
|
||||||
```
|
```
|
||||||
|
|
||||||
Providers using this pattern will behave as if they provide `MyService` as [DI token][DI_TOKEN]
|
Providers using this pattern will behave as if they provide `MyService` as [DI token][DI_TOKEN]
|
||||||
with the value of `undefined`. This is not the case in Ivy where such providers will be interpreted
|
with the value of `undefined`.
|
||||||
as if `useClass: MyService` is specified. This means that these providers will behave differently
|
This is not the case in Ivy where such providers will be interpreted as if `useClass: MyService` is specified.
|
||||||
when updating to version 9 and above. To ensure that the provider behaves the same as before, the
|
This means that these providers will behave differently when updating to version 9 and above.
|
||||||
DI value should be explicitly set to `undefined`.
|
To ensure that the provider behaves the same as before, the DI value should be explicitly set to `undefined`.
|
||||||
|
|
||||||
### When should I be adding `@Injectable()` decorators to classes?
|
### When should I be adding `@Injectable()` decorators to classes?
|
||||||
|
|
||||||
Any class that is provided must have an `@Injectable()` decorator. The decorator is necessary
|
Any class that is provided must have an `@Injectable()` decorator.
|
||||||
for the framework to properly create an instance of that class through DI.
|
The decorator is necessary for the framework to properly create an instance of that class through DI.
|
||||||
|
|
||||||
However, classes which are already decorated with `@Pipe`, `@Component` or `@Directive` do not
|
However, classes which are already decorated with `@Pipe`, `@Component` or `@Directive` do not need both decorators.
|
||||||
need both decorators. The existing class decorator already instructs the compiler to generate the
|
The existing class decorator already instructs the compiler to generate the
|
||||||
needed information.
|
needed information.
|
||||||
|
|
||||||
### Should I update my library?
|
### Should I update my library?
|
||||||
|
|
||||||
Yes, if your library has any classes that are meant to be injected, they should be updated with
|
Yes, if your library has any classes that are meant to be injected, they should be updated with the `@Injectable()` decorator.
|
||||||
the `@Injectable()` decorator. In a future version of Angular, a missing `@Injectable()` decorator
|
In a future version of Angular, a missing `@Injectable()` decorator will always throw an error.
|
||||||
will always throw an error.
|
|
||||||
|
|
||||||
Additionally, providers in your library that follow the described `{provide: X}` pattern should be
|
Additionally, providers in your library that follow the described `{provide: X}` pattern should be updated to specify an explicit value.
|
||||||
updated to specify an explicit value. Without explicit value, these providers can behave
|
Without explicit value, these providers can behave differently based on the Angular version in applications consuming your library.
|
||||||
differently based on the Angular version in applications consuming your library.
|
|
||||||
|
|
||||||
[DI_TOKEN]: guide/glossary#di-token
|
[DI_TOKEN]: guide/glossary#di-token
|
||||||
|
|
|
@ -29,7 +29,8 @@ The symbol is loaded by importing the `@angular/localize/init` module, which has
|
||||||
|
|
||||||
## Why is this migration necessary?
|
## Why is this migration necessary?
|
||||||
|
|
||||||
Prior to Angular version 9, Angular's internationalization (i18n) system inlined translated messages into the compiled output as part of this template compilation. This approach required running the template compiler once per target locale, often leading to slow production build times.
|
Prior to Angular version 9, Angular's internationalization (i18n) system inlined translated messages into the compiled output as part of this template compilation.
|
||||||
|
This approach required running the template compiler once per target locale, often leading to slow production build times.
|
||||||
|
|
||||||
In the new i18n system, the Angular compiler tags i18n messages in the compiled code with a global `$localize` handler.
|
In the new i18n system, the Angular compiler tags i18n messages in the compiled code with a global `$localize` handler.
|
||||||
The inlining of translations then occurs as a post-compilation step for each locale.
|
The inlining of translations then occurs as a post-compilation step for each locale.
|
||||||
|
@ -55,7 +56,8 @@ if your app uses Angular's i18n APIs.
|
||||||
|
|
||||||
## Why is my tslint failing?
|
## Why is my tslint failing?
|
||||||
|
|
||||||
The import of `@angular/localize/init` may cause a tslint error for `no-import-side-effect` because it adds to the global context (that is, a side effect). To fix this error, add the following to your `tslint.config`:
|
The import of `@angular/localize/init` may cause a tslint error for `no-import-side-effect` because it adds to the global context (that is, a side effect).
|
||||||
|
To fix this error, add the following to your `tslint.config`:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
|
|
||||||
|
|
|
@ -2,19 +2,24 @@
|
||||||
|
|
||||||
## Migration Overview
|
## Migration Overview
|
||||||
|
|
||||||
The `Renderer` class has been marked as deprecated since Angular version 4. This section provides guidance on migrating from this deprecated API to the newer `Renderer2` API and what it means for your app.
|
The `Renderer` class has been marked as deprecated since Angular version 4.
|
||||||
|
This section provides guidance on migrating from this deprecated API to the newer `Renderer2` API and what it means for your app.
|
||||||
|
|
||||||
## Why should I migrate to Renderer2?
|
## Why should I migrate to Renderer2?
|
||||||
|
|
||||||
The deprecated `Renderer` class has been removed in version 9 of Angular, so it's necessary to migrate to a supported API. Using `Renderer2` is the recommended strategy because it supports a similar set of functionality to `Renderer`. The API surface is quite large (with 19 methods), but the schematic should simplify this process for your applications.
|
The deprecated `Renderer` class has been removed in version 9 of Angular, so it's necessary to migrate to a supported API.
|
||||||
|
Using `Renderer2` is the recommended strategy because it supports a similar set of functionality to `Renderer`.
|
||||||
|
The API surface is quite large (with 19 methods), but the schematic should simplify this process for your applications.
|
||||||
|
|
||||||
## Is there action required on my end?
|
## Is there action required on my end?
|
||||||
|
|
||||||
No. The schematic should handle most cases with the exception of `Renderer.animate()` and `Renderer.setDebugInfo()`, which already aren’t supported.
|
No.
|
||||||
|
The schematic should handle most cases with the exception of `Renderer.animate()` and `Renderer.setDebugInfo()`, which already aren't supported.
|
||||||
|
|
||||||
## What are the `__ngRendererX` methods? Why are they necessary?
|
## What are the `__ngRendererX` methods? Why are they necessary?
|
||||||
|
|
||||||
Some methods either don't have exact equivalents in `Renderer2`, or they correspond to more than one expression. For example, both renderers have a `createElement()` method, but they're not equal because a call such as `renderer.createElement(parentNode, namespaceAndName)` in the `Renderer` corresponds to the following block of code in `Renderer2`:
|
Some methods either don't have exact equivalents in `Renderer2`, or they correspond to more than one expression.
|
||||||
|
For example, both renderers have a `createElement()` method, but they're not equal because a call such as `renderer.createElement(parentNode, namespaceAndName)` in the `Renderer` corresponds to the following block of code in `Renderer2`:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
const [namespace, name] = splitNamespace(namespaceAndName);
|
const [namespace, name] = splitNamespace(namespaceAndName);
|
||||||
|
@ -25,7 +30,10 @@ if (parentNode) {
|
||||||
return el;
|
return el;
|
||||||
```
|
```
|
||||||
|
|
||||||
Migration has to guarantee that the return values of functions and types of variables stay the same. To handle the majority of cases safely, the schematic declares helper functions at the bottom of the user's file. These helpers encapsulate your own logic and keep the replacements inside your code down to a single function call. Here's an example of how the `createElement()` migration looks:
|
Migration has to guarantee that the return values of functions and types of variables stay the same.
|
||||||
|
To handle the majority of cases safely, the schematic declares helper functions at the bottom of the user's file.
|
||||||
|
These helpers encapsulate your own logic and keep the replacements inside your code down to a single function call.
|
||||||
|
Here's an example of how the `createElement()` migration looks:
|
||||||
|
|
||||||
|
|
||||||
**Before:**
|
**Before:**
|
||||||
|
|
|
@ -103,52 +103,35 @@ class Dir extends Base {
|
||||||
|
|
||||||
### Migrating classes that use DI
|
### Migrating classes that use DI
|
||||||
|
|
||||||
When a class has a `@Directive()` or `@Component()` decorator,
|
When a class has a `@Directive()` or `@Component()` decorator, the Angular compiler generates extra code to inject dependencies into the constructor.
|
||||||
the Angular compiler generates extra code to inject dependencies into
|
When using inheritance, Ivy needs both the parent class and the child class to apply a decorator to generate the correct code.
|
||||||
the constructor. When using inheritance, Ivy needs both the parent class
|
|
||||||
and the child class to apply a decorator to generate the correct code.
|
|
||||||
|
|
||||||
You can think of this change as two cases: a parent class is missing a
|
You can think of this change as two cases: a parent class is missing a
|
||||||
decorator or a child class is missing a decorator. In both scenarios,
|
decorator or a child class is missing a decorator.
|
||||||
Angular's runtime needs additional information from the compiler.
|
In both scenarios, Angular's runtime needs additional information from the compiler.
|
||||||
This additional information comes from adding decorators.
|
This additional information comes from adding decorators.
|
||||||
|
|
||||||
|
|
||||||
#### Decorator missing from parent class
|
#### Decorator missing from parent class
|
||||||
|
|
||||||
When the decorator is missing from the parent class,
|
When the decorator is missing from the parent class, the subclass will inherit a constructor from a class for which the compiler did not generate special constructor info (because it was not decorated as a directive).
|
||||||
the subclass will inherit a constructor from a class for
|
When Angular then tries to create the subclass, it doesn't have the correct info to create it.
|
||||||
which the compiler did not generate special constructor
|
|
||||||
info (because it was not decorated as a directive).
|
|
||||||
When Angular then tries to create the subclass,
|
|
||||||
it doesn't have the correct info
|
|
||||||
to create it.
|
|
||||||
|
|
||||||
In View Engine, the compiler has global knowledge, so it
|
In View Engine, the compiler has global knowledge, so it can look up the missing data.
|
||||||
can look up the missing data. However, the Ivy compiler
|
However, the Ivy compiler only processes each directive in isolation.
|
||||||
only processes each directive in isolation. This means that
|
This means that compilation can be faster, but the compiler can't automatically infer the same information as before.
|
||||||
compilation can be faster, but the compiler can't
|
Adding the `@Directive()` explicitly provides this information.
|
||||||
automatically infer the same
|
|
||||||
information as before. Adding the `@Directive()` explicitly
|
|
||||||
provides this information.
|
|
||||||
|
|
||||||
In the future, add `@Directive()` to base classes that
|
In the future, add `@Directive()` to base classes that do not already have decorators and are extended by directives.
|
||||||
do not already have decorators and are extended by directives.
|
|
||||||
|
|
||||||
#### Decorator missing from child class
|
#### Decorator missing from child class
|
||||||
|
|
||||||
When the child class is missing the decorator, the
|
When the child class is missing the decorator, the child class inherits from the parent class yet has no decorators of its own.
|
||||||
child class inherits from the
|
Without a decorator, the compiler has no way of knowing that the class is a `@Directive` or `@Component`, so it doesn't generate the proper instructions for the directive.
|
||||||
parent class yet has no decorators of its own.
|
|
||||||
Without a decorator, the compiler has no way of knowing
|
|
||||||
that the class is a `@Directive` or `@Component`, so
|
|
||||||
it doesn't generate the proper instructions for the directive.
|
|
||||||
|
|
||||||
|
|
||||||
### Migrating classes that use field decorators
|
### Migrating classes that use field decorators
|
||||||
|
|
||||||
In ViewEngine, base classes with field decorators like `@Input()` worked
|
In ViewEngine, base classes with field decorators like `@Input()` worked even when the class did not have a `@Directive()` or `@Component()` decorator.
|
||||||
even when the class did not have a `@Directive()` or `@Component()` decorator.
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
|
@ -165,52 +148,41 @@ class Dir extends Base {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
However, this example won't compile with Ivy because the `Base` class
|
However, this example won't compile with Ivy because the `Base` class _requires_ either a `@Directive()` or `@Component()` decorator to generate code for inputs, outputs, queries, and host bindings.
|
||||||
_requires_ either a `@Directive()` or `@Component()` decorator to generate
|
|
||||||
code for inputs, outputs, queries, and host bindings.
|
|
||||||
|
|
||||||
Always requiring a class decorator leads to two main benefits for Angular:
|
Always requiring a class decorator leads to two main benefits for Angular:
|
||||||
|
|
||||||
1. The previous behavior was inconsistent. Some Angular features required a decorator (dependency injection), but others did not. Now, all Angular features consistently require a class decorator.
|
1. The previous behavior was inconsistent.
|
||||||
|
Some Angular features required a decorator (dependency injection), but others did not.
|
||||||
|
Now, all Angular features consistently require a class decorator.
|
||||||
|
|
||||||
1. Supporting undecorated classes increases the code size and complexity of Angular. Always requiring class decorators allows the framework to become smaller and simpler for all users.
|
1. Supporting undecorated classes increases the code size and complexity of Angular.
|
||||||
|
Always requiring class decorators allows the framework to become smaller and simpler for all users.
|
||||||
|
|
||||||
|
|
||||||
## What does it mean to have a `@Directive()` decorator with no metadata inside of it?
|
## What does it mean to have a `@Directive()` decorator with no metadata inside of it?
|
||||||
|
|
||||||
The presence of the `@Directive` decorator causes Angular to generate
|
The presence of the `@Directive` decorator causes Angular to generate extra code for the affected class.
|
||||||
extra code for the affected class. If that decorator includes no
|
If that decorator includes no properties (metadata), the directive won't be matched to elements or instantiated directly, but other classes that _extend_ the directive class will inherit this generated code.
|
||||||
properties (metadata),
|
You can think of this as an "abstract" directive.
|
||||||
the directive won't be matched to elements or instantiated
|
|
||||||
directly, but other classes that _extend_ the
|
|
||||||
directive class will inherit this generated code. You can think of
|
|
||||||
this as an "abstract" directive.
|
|
||||||
|
|
||||||
Adding an abstract directive to an `NgModule` will cause an error.
|
Adding an abstract directive to an `NgModule` will cause an error.
|
||||||
A directive must have a `selector` property defined in order to match some element in a template.
|
A directive must have a `selector` property defined in order to match some element in a template.
|
||||||
|
|
||||||
## When do I need a `@Directive()` decorator without a selector?
|
## When do I need a `@Directive()` decorator without a selector?
|
||||||
|
|
||||||
If you're using dependency injection, or any Angular-specific
|
If you're using dependency injection, or any Angular-specific feature, such as `@HostBinding()`, `@ViewChild()`, or `@Input()`, you need a `@Directive()` or `@Component()` decorator.
|
||||||
feature, such as `@HostBinding()`, `@ViewChild()`, or `@Input()`, you need a
|
The decorator lets the compiler know to generate the correct instructions to create that class and any classes that extend it.
|
||||||
`@Directive()` or `@Component()` decorator.
|
If you don't want to use that base class as a directive directly, leave the selector blank.
|
||||||
The decorator lets the compiler know to generate the correct
|
If you do want it to be usable independently, fill in the metadata as usual.
|
||||||
instructions to create that class and any classes that extend it.
|
|
||||||
If you don't want to use that base class as a directive directly, leave
|
|
||||||
the selector blank. If you do want it to be usable independently,
|
|
||||||
fill in the metadata as usual.
|
|
||||||
|
|
||||||
Classes that don't use Angular features don't need an Angular decorator.
|
Classes that don't use Angular features don't need an Angular decorator.
|
||||||
|
|
||||||
## I'm a library author. Should I add the `@Directive()` decorator to base classes?
|
## I'm a library author. Should I add the `@Directive()` decorator to base classes?
|
||||||
|
|
||||||
As support for selectorless decorators is introduced in
|
As support for selectorless decorators is introduced in Angular version 9, if you want to support Angular version 8 and earlier, you shouldn't add a selectorless `@Directive()` decorator.
|
||||||
Angular version 9, if you want to support Angular version 8 and earlier, you
|
You can either add `@Directive()` with a selector or move the Angular-specific features to affected subclasses.
|
||||||
shouldn't add a selectorless `@Directive()` decorator.
|
|
||||||
You can either add `@Directive()` with a selector or
|
|
||||||
move the Angular-specific features to affected subclasses.
|
|
||||||
|
|
||||||
## What about applications using non-migrated libraries?
|
## What about applications using non-migrated libraries?
|
||||||
|
|
||||||
`ngcc` should transform any non-migrated libraries to generate the proper code.
|
`ngcc` should transform any non-migrated libraries to generate the proper code.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue