From official docs we know that
Component decorator allows you to mark a class as an Angular component and provide additional metadata that determines how the component should be processed, instantiated and used at runtime.
But I would like to go deeper and understand what Component decorator really does except providing additional metadata.
I dived into source code and found that all decorators are created with help of makeDecorator function. And here I got lost. Where is the difference for example for Component and ngModule decorators? Are they doing the same thing? Don't think so.
Like an answer it would be great to have step by step description what I should do to recreate Component Decorator without makeDecorator function.
UPD: and, Yes, of course, I know how TypeScript Decorators work.
Components are the most basic UI building block of an Angular app. An Angular app contains a tree of Angular components. Angular components are a subset of directives, always associated with a template. Unlike other directives, only one component can be instantiated for a given element in a template.
Parameter decorators must accept three parameters: the class prototype or constructor, the name of the member, and the index of the parameter.
A component is an instance of a metadata type.
The whole purpose of Angular decorators is to store metadata about a class, method, or property. When you configure a component, you are providing a metadata for that class that tells Angular that you have a component, and that component has a specific configuration.
But I would like to go deeper and understand what Component decorator really does except providing additional metadata.
Why does it need to be anything more? It's said that the argument passed to the @Component
decorator function is the component metatdata. So that is the main responsibility, to provide metadata.
The easiest way, if you want to reproduce something similar is to
Install the reflect-metadata
.
npm install --save reflect-metadata
Create the decorator function1
import 'reflect-metadata';
interface MyComponentMetadata {
template?: string;
selector?: string;
}
function MyComponent(metadata: MyComponentMetadata) {
return function(ctor: Function) {
// add metadata to constructor
Reflect.defineMetadata('annotations', metadata, ctor);
}
}
Use it
@MyComponent({
selector: 'component',
template: '<hello></hello>'
})
class HelloComponent {
}
Now when you need to get the metadata, just do
let metadata = Reflect.getMetadata('annotations', HelloComponent);
The purpose of the metadata is to provide information for Angular to know what to do with the class. So the decorator doesn't really need to be anything more than just a metadata provider. Angular decides what to do with the metadata, not the decorator function.
1 - See TypeScript documentation on decorators
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With