@Component({
selector: "thingy",
template: `foo`
})
class MyComponent {
}
Decorators
We’ve seen in the quickstart that in Angular 2 we can decorate a class with extra info using the @
syntax, like so:
This is a new feature of Javascript that will probably make it into ES7. The same functionality is already available in Typescript however so we can use it.
It allows us to decorate classes and functions, similar to annotations in java and decorators in python.
Specific implementations might be hard to understand and read but the concept is actually quite simple.
Simple no-argument decorator
I’m going to explain by creating a decorator called @course
for our Person class
@course
class Person {
firstName;
lastName;
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
@course
is just a function, like so:
function course(target) {
Object.defineProperty(target.prototype, 'course', {value: () => "Angular 1"})
}
The first argument to the course
function is the target
.
This is the thing the decorator is attached to, so for a class it’s going to be the function constructor for that class, the under-the-hood implementation of a class.
Knowing this we can actually dynamically add a function to our Person class by using the Object.defineProperty
syntax,
The details of the Object.defineProperty
function are beyond the scope of this chapter. We use it to add a function called course
onto the class it decorates and for now this function just returns the string "Angular 2".
We can now call asim.course()
and this prints out "Angular 2"
:
let asim = new Person("Asim", "Hussain");
console.log(asim.course()); // Angular 2
Decorators with arguments
But how do we pass arguments to our decorator, like the way the @Component
decorator works?
We create a function that returns a decorator, like so:
function Course(config) { // 1
return function (target) {
Object.defineProperty(
target.prototype,
'course',
{value: () => config.course} // 2
)
}
}
-
We pass a
config
object to the outerCourse
function. -
Then use that
config
in the returned inner decorator function.
Now we can use this decorator like so:
@Student({
course: "Angular 2"
})
class Person {
}
Summary
Decorators are a new feature of Typescript and used throughout the Angular 2 code, but they are nothing to be scared of.
With decorators we can configure and customise our classes at design time.
They are just functions that can be used to add meta-data, properties or functions to the thing they are attached to.
A collection of useful decorators, for use in your projects or just to read and learn, can be found here: https://github.com/jayphelps/core-decorators.js