0% found this document useful (0 votes)
81 views13 pages

Angular Decorators: @ngmodule

The document discusses Angular decorators and the different types: class, property, method, and parameter decorators. It provides examples of common Angular decorators like @Component, @Input, @Output, @ViewChild, and @ContentChild and describes what they are used for and how to implement them.

Uploaded by

ANKIT KUMAR
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
81 views13 pages

Angular Decorators: @ngmodule

The document discusses Angular decorators and the different types: class, property, method, and parameter decorators. It provides examples of common Angular decorators like @Component, @Input, @Output, @ViewChild, and @ContentChild and describes what they are used for and how to implement them.

Uploaded by

ANKIT KUMAR
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 13

Angular Decorators

Before we look at creating a custom decorator and why/how Angular uses them, let’s look at the
different types of decorators that Angular offers. There are four main types:

● Class decorators: @Component and @NgModule


● Property decorators: for properties inside classes, e.g. @Input and @Output
● Method decorators: for methods inside classes, e.g. @HostListener
● Parameter decorators for parameters inside class constructors, e.g. @Inject

@NgModule: Decorator that marks the following class as NgModule


@Component({...})
class MyComponent() {}
Declares that a class is a component and provides metadata about the component.

@Directive({...})
class MyDirective() {}
Declares that a class is a directive and provides metadata about the directive.

@Pipe({...})
class MyPipe() {}
Declares that a class is a pipe and provides metadata about the pipe.

@Injectable()
class MyService() {}
Declares that a class has dependencies that should be injected into the constructor when the
dependency injector is creating an instance of this class.

Property Decorators: Property decorators work with properties of classes.


@Input() myProperty; Declares an input property that you can

update via property binding (example: <my-

cmp [myProperty]="someExpression">).

@Output() myEvent = new Declares an output property that fires


EventEmitter();
events that you can subscribe to with an

event binding (example: <my-cmp

(myEvent)="doSomething()">).

@HostBinding('class.valid') isValid; Binds a host element property (here, the

CSS class valid) to a directive/component

property (isValid).

@HostListener('click', ['$event']) Subscribes to a host element event (click)


onClick(e) {...}
with a directive/component method

(onClick), optionally passing an argument

($event).

@ContentChild(myPredicate) Binds the first result of the component


myChildComponent;
content query (myPredicate) to a property
(myChildComponent) of the class.

@ContentChildren(myPredicate) Binds the results of the component content


myChildComponents;
query (myPredicate) to a property

(myChildComponents) of the class.

@ViewChild(myPredicate) Binds the first result of the component view


myChildComponent;
query (myPredicate) to a property

(myChildComponent) of the class. Not

available for directives.

@ViewChildren(myPredicate) Binds the results of the component view


myChildComponents;
query (myPredicate) to a property

(myChildComponents) of the class. Not

available for directives.

Differences between @viewChild and @contentChild

@component:
https://docs.google.com/document/d/1ale3W25RZYmXh4rVSjagC01pg6Plw600s-
b3WZhBMOo/edit

@Directive:
https://docs.google.com/document/d/1rm9hgZWN6LQ_JlW9pGfby50QsFXAyeEnHnHEy-
svNdI/edit?usp=sharing
@input:
npm Package: @angular/core
Module: import { Input } from '@angular/core';
Source: core/src/metadata/directives.ts
@Input({
bindingPropertyName?: string
})
@output:
npm Package: @angular/core

Module: import { Output } from '@angular/core';


Source: core/src/metadata/directives.ts
@Output({
bindingPropertyName?: string
})

@viewChild:
https://angular.io/api/core/ViewChild

npm Package: @angular/core


Module: import { ViewChild } from '@angular/core';
Source: core/src/metadata/di.ts

See here:

The local variable approach is simple and easy. But it is limited because the parent-child wiring must

be done entirely within the parent template. The parent component itself has no access to the child.

You can't use the local variable technique if an instance of the parent component class must read or

write child component values or must call child component methods.

When the parent component class requires that kind of access, inject the child component into the

parent as a ViewChild.

How To Use:
import {AfterViewInit, Component, Directive, ViewChild} from '@angular/core';

1.

2. @Directive({selector: 'child-directive'})
3. class ChildDirective {

4. }

5.

6. @Component({selector: 'someCmp', templateUrl: 'someCmp.html'})

7. class SomeCmp implements AfterViewInit {

8. @ViewChild(ChildDirective) child: ChildDirective;

9.

10. ngAfterViewInit() {

11. // child is set

12. }

13. }

Description: You can use ViewChild to get the first element or the directive matching the
selector from the view DOM. If the view DOM changes, and a new child matches the selector,
the property will be updated.

View queries are set before the ngAfterViewInit callback is called.

Metadata Properties:

● selector - the directive type or the name used for querying.

● read - read a different token from the queried elements.

content_copy

1. import {Component, Directive, Input, ViewChild} from '@angular/core';

2.
3. @Directive({selector: 'pane'})

4. export class Pane {

5. @Input() id: string;

6. }

7.

8. @Component({

9. selector: 'example-app',

10. template: `

11. <pane id="1" *ngIf="shouldShow"></pane>

12. <pane id="2" *ngIf="!shouldShow"></pane>

13.

14. <button (click)="toggle()">Toggle</button>

15.

16. <div>Selected: {{selectedPane}}</div>

17. `,

18. })

19. export class ViewChildComp {

20. @ViewChild(Pane)

21. set pane(v: Pane) {

22. setTimeout(() => { this.selectedPane = v.id; }, 0);

23. }

24. selectedPane: string = '';

25. shouldShow = true;

26. toggle() { this.shouldShow = !this.shouldShow; }

27. }
@viewChildren: You can use ViewChildren to get the QueryList of elements or directives from the
view DOM. Any time a child element is added, removed, or moved, the query list will be updated, and
the changes observable of the query list will emit a new value.
View queries are set before the ngAfterViewInit callback is called.

@ContentChild:
npm Package: @angular/core
Module: import { ContentChild } from '@angular/core';
Source: core/src/metadata/di.ts
How To Use:
import {AfterContentInit, ContentChild, Directive} from '@angular/core';

1.

2. @Directive({selector: 'child-directive'})

3. class ChildDirective {

4. }

5.

6. @Directive({selector: 'someDir'})

7. class SomeDir implements AfterContentInit {

8. @ContentChild(ChildDirective) contentChild: ChildDirective;

9.

10. ngAfterContentInit() {

11. // contentChild is set

12. }

13. }

Description: You can use ContentChild to get the first element or the directive matching the
selector from the content DOM. If the content DOM changes, and a new child matches the
selector, the property will be updated.
Content queries are set before the ngAfterContentInit callback is called.

Metadata Properties:

● selector - the directive type or the name used for querying.

● read - read a different token from the queried element.

Let's look at an example:

1. import {Component, ContentChild, Directive, Input} from '@angular/core';

2.

3. @Directive({selector: 'pane'})

4. export class Pane {

5. @Input() id: string;

6. }

7.

8. @Component({

9. selector: 'tab',

10. template: `

11. <div>pane: {{pane?.id}}</div>

12. `

13. })

14. export class Tab {

15. @ContentChild(Pane) pane: Pane;

16. }

17.
18. @Component({

19. selector: 'example-app',

20. template: `

21. <tab>

22. <pane id="1" *ngIf="shouldShow"></pane>

23. <pane id="2" *ngIf="!shouldShow"></pane>

24. </tab>

25.

26. <button (click)="toggle()">Toggle</button>

27. `,

28. })

29. export class ContentChildComp {

30. shouldShow = true;

31.

32. toggle() { this.shouldShow = !this.shouldShow; }

33. }

@ContentChildren:

npm Package: @angular/core


Module: import { ContentChildren } from '@angular/core';
Source: core/src/metadata/di.ts

How To Use:
import {AfterContentInit, ContentChildren, Directive, QueryList} from '@angular/core';

1.

2. @Directive({selector: 'child-directive'})

3. class ChildDirective {

4. }

5.

6. @Directive({selector: 'someDir'})

7. class SomeDir implements AfterContentInit {

8. @ContentChildren(ChildDirective) contentChildren: QueryList<ChildDirective>;

9.

10. ngAfterContentInit() {

11. // contentChildren is set

12. }

13. }

Description: You can use ContentChildren to get the QueryList of elements or directives from
the content DOM. Any time a child element is added, removed, or moved, the query list will be
updated, and the changes observable of the query list will emit a new value.

Content queries are set before the ngAfterContentInit callback is called.

Metadata Properties:

● selector - the directive type or the name used for querying.

● descendants - include only direct children or all descendants.

● read - read a different token from the queried elements.

● import {Component, ContentChildren, Directive, Input, QueryList} from '@angular/core';

● @Directive({selector: 'pane'})
● export class Pane {

● @Input() id: string;

● }

● @Component({

● selector: 'tab',

● template: `

● <div class="top-level">Top level panes: {{serializedPanes}}</div>

● <div class="nested">Arbitrary nested panes: {{serializedNestedPanes}}</div>

● `

● })

● export class Tab {

● @ContentChildren(Pane) topLevelPanes: QueryList<Pane>;

● @ContentChildren(Pane, {descendants: true}) arbitraryNestedPanes: QueryList<Pane>;

● get serializedPanes(): string {

● return this.topLevelPanes ? this.topLevelPanes.map(p => p.id).join(', ') : '';

● }

● get serializedNestedPanes(): string {

● return this.arbitraryNestedPanes ? this.arbitraryNestedPanes.map(p => p.id).join(', ') :

'';

● }

● }

● @Component({

● selector: 'example-app',

● template: `
● <tab>

● <pane id="1"></pane>

● <pane id="2"></pane>

● <pane id="3" *ngIf="shouldShow">

● <tab>

● <pane id="3_1"></pane>

● <pane id="3_2"></pane>

● </tab>

● </pane>

● </tab>

● <button (click)="show()">Show 3</button>

● `,

● })

● export class ContentChildrenComp {

● shouldShow = false;

● show() { this.shouldShow = true; }

● }

Difference between provider and viewProvider:

@ViewChildren look for elements in Shadow DOM while @ContentChildren look for them
in Light DOM.
https://stackoverflow.com/questions/34326745/whats-the-difference-between-viewchild-and-
contentchild

https://ng2.codecraft.tv/components/viewchildren-and-
contentchildren/#_viewchild_referencing_a_template_local_variable

You might also like