docs(aio): update metadata documentation to include expression lowering (#19203)
This commit is contained in:
parent
627f04883a
commit
f7c7038171
|
@ -66,7 +66,7 @@ You can think of `.metadata.json` as a diagram of the overall structure of a dec
|
|||
|
||||
<div class="l-sub-section">
|
||||
|
||||
Angular's [schema.ts](https://github.com/angular/angular/blob/master/packages/compiler-cli/src/metadata/schema.ts)
|
||||
Angular's [schema.ts](https://github.com/angular/angular/blob/master/packages/tsc-wrapped/src/schema.ts)
|
||||
describes the JSON format as a collection of TypeScript interfaces.
|
||||
|
||||
</div>
|
||||
|
@ -149,6 +149,8 @@ export function serverFactory() {
|
|||
})
|
||||
```
|
||||
|
||||
Beginning in version 5, the compiler automatically performs this rewritting while emitting the `.js` file.
|
||||
|
||||
### Limited function calls
|
||||
|
||||
The _collector_ can represent a function call or object creation with `new` as long as the syntax is valid. The _collector_ only cares about proper syntax.
|
||||
|
@ -181,7 +183,7 @@ const template = '<div>{{hero.name}}</div>';
|
|||
selector: 'app-hero',
|
||||
template: template
|
||||
})
|
||||
class HeroComponent {
|
||||
export class HeroComponent {
|
||||
@Input() hero: Hero;
|
||||
}
|
||||
```
|
||||
|
@ -196,7 +198,7 @@ The effect is the same as if you had written:
|
|||
selector: 'app-hero',
|
||||
template: '<div>{{hero.name}}</div>'
|
||||
})
|
||||
class HeroComponent {
|
||||
export class HeroComponent {
|
||||
@Input() hero: Hero;
|
||||
}
|
||||
```
|
||||
|
@ -212,7 +214,7 @@ const template = '<div>{{hero.name}}</div>';
|
|||
selector: 'app-hero',
|
||||
template: template + '<div>{{hero.title}}</div>'
|
||||
})
|
||||
class HeroComponent {
|
||||
export class HeroComponent {
|
||||
@Input() hero: Hero;
|
||||
}
|
||||
```
|
||||
|
@ -269,7 +271,7 @@ Data bound properties must also be public.
|
|||
selector: 'app-root',
|
||||
template: '<h1>{{title}}</h1>'
|
||||
})
|
||||
class AppComponent {
|
||||
export class AppComponent {
|
||||
private title = 'My App'; // Bad
|
||||
}
|
||||
```
|
||||
|
@ -329,7 +331,7 @@ You might use `wrapInArray()` like this:
|
|||
@NgModule({
|
||||
declarations: wrapInArray(TypicalComponent)
|
||||
})
|
||||
class TypicalModule {}
|
||||
export class TypicalModule {}
|
||||
```
|
||||
|
||||
The compiler treats this usage as if you had written:
|
||||
|
@ -338,7 +340,7 @@ The compiler treats this usage as if you had written:
|
|||
@NgModule({
|
||||
declarations: [TypicalComponent]
|
||||
})
|
||||
class TypicalModule {}
|
||||
export class TypicalModule {}
|
||||
```
|
||||
|
||||
The collector is simplistic in its determination of what qualifies as a macro
|
||||
|
@ -348,6 +350,49 @@ The Angular [`RouterModule`](api/router/RouterModule) exports two macro static m
|
|||
Review the [source code](https://github.com/angular/angular/blob/master/packages/router/src/router_module.ts#L139 "RouterModule.forRoot source code")
|
||||
for these methods to see how macros can simplify configuration of complex Angular modules.
|
||||
|
||||
### Metadata rewriting
|
||||
|
||||
The compiler treats object literals containing the fields `useClass`, `useValue`, `useFactory`, and `data` specially. The compiler converts the expression initializing one of these fields into an exported variable, which replaces the expression. This process of rewriting these expressions removes all the restrictions on what can be in them because
|
||||
the compiler doesn't need to know the expression's value—it just needs to be able to generate a reference to the value.
|
||||
|
||||
|
||||
|
||||
You might write something like:
|
||||
|
||||
```ts
|
||||
class TypicalServer {
|
||||
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
providers: [{provide: SERVER, useFactory: () => TypicalServer}]
|
||||
})
|
||||
export class TypicalModule {}
|
||||
```
|
||||
|
||||
Without rewriting, this would be invalid because lambdas are not supported and `TypicalServer` is not exported.
|
||||
|
||||
To allow this, the compiler automatically rewrites this to something like:
|
||||
|
||||
```ts
|
||||
class TypicalServer {
|
||||
|
||||
}
|
||||
|
||||
export const ɵ0 = () => new TypicalServer();
|
||||
|
||||
@NgModule({
|
||||
providers: [{provide: SERVER, useFactory: ɵ0}]
|
||||
})
|
||||
export class TypicalModule {}
|
||||
```
|
||||
|
||||
This allows the compiler to generate a reference to `ɵ0` in the
|
||||
factory without having to know what the value of `ɵ0` contains.
|
||||
|
||||
The compiler does the rewriting during the emit of the `.js` file. This doesn't rewrite the `.d.ts` file, however, so TypeScript doesn't recognize it as being an export. Thus, it does not pollute the ES module's exported API.
|
||||
|
||||
|
||||
## Metadata Errors
|
||||
|
||||
The following are metadata errors you may encounter, with explanations and suggested corrections.
|
||||
|
|
Loading…
Reference in New Issue