Building Nested Components
Using a Component
As a Directive As a Routing target
App Full
Component page
OR Nested style
Component view
<body>
<pm-root></pm-root>
</body>
What Makes a Component Nest-able?
Its template only manages a fragment of a
larger view
It has a selector
It optionally communicates with its
container
Module
Building a Nested Component
Overview
Using a Nested Component
Passing Data to a Nested Component
Using @Input
Raising an Event from a Nested
Component Using @Output
Building a Nested Component
Container Component
Template
Nested Component <pm-star> </pm-star>
Template
Class
Class
Building a Nested Component
Container Component
Template
Nested Component
<pm-star> </pm-star>
Template
Input
Output
Class
Class
Product List View
Product List View
Using a Nested Component as a Directive
[Link] [Link]
@Component({ @Component({
selector: 'pm-products', selector: 'pm-star',
templateURL: './[Link]' templateURL: './[Link]'
}) })
export class ProductListComponent { } export class StarComponent {
rating: number;
starWidth: number;
[Link] }
<td>
{{ [Link] | number }}
</td>
Using a Nested Component as a Directive
[Link] [Link]
@Component({ @Component({
selector: 'pm-products', selector: 'pm-star',
templateURL: './[Link]' templateURL: './[Link]'
}) })
export class ProductListComponent { } export class StarComponent {
rating: number;
starWidth: number;
[Link] }
<td>
<pm-star></pm-star>
</td>
BrowserModule FormsModule
AppModule
AppComponent
ProductList -
Component
ConvertToSpaces
Pipe
Imports
Exports
Declarations StarComponent
Providers
Bootstrap
Telling Angular About Our Component
[Link]
...
import { StarComponent } from './shared/[Link]';
@NgModule({
imports: [
BrowserModule,
FormsModule ],
declarations: [
AppComponent,
ProductListComponent,
ConvertToSpacesPipe,
StarComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Passing Data to a Nested Component (@Input)
Container Component
Template
Nested Component
<pm-star> </pm-star>
Template
Input @Input()
Class
Class
Passing Data to a Nested Component (@Input)
[Link] [Link]
@Component({ @Component({
selector: 'pm-products', selector: 'pm-star',
templateURL: './[Link]' templateURL: './[Link]'
}) })
export class ProductListComponent { } export class StarComponent {
@Input() rating: number;
starWidth: number;
[Link] }
<td>
<pm-star></pm-star>
</td>
Passing Data to a Nested Component (@Input)
[Link] [Link]
@Component({ @Component({
selector: 'pm-products', selector: 'pm-star',
templateURL: './[Link]' templateURL: './[Link]'
}) })
export class ProductListComponent { } export class StarComponent {
@Input() rating: number;
starWidth: number;
[Link] }
<td>
<pm-star [rating]='[Link]'>
</pm-star>
</td>
Raising an Event (@Output)
Container Component
Template
Nested Component
<pm-star> </pm-star>
Template
Input @Input()
Output @Output()
Class
Class
Raising an Event (@Output)
[Link] [Link]
@Component({ @Component({
selector: 'pm-products', selector: 'pm-star',
templateURL: './[Link]' templateURL: './[Link]'
}) })
export class ProductListComponent { } export class StarComponent {
@Input() rating: number;
starWidth: number;
@Output() notify: EventEmitter<string> =
new EventEmitter<string>();
}
[Link]
<td>
<pm-star [rating]='[Link]'>
</pm-star>
</td>
Raising an Event (@Output)
[Link] [Link]
@Component({ @Component({
selector: 'pm-products', selector: 'pm-star',
templateURL: './[Link]' templateURL: './[Link]'
}) })
export class ProductListComponent { } export class StarComponent {
@Input() rating: number;
starWidth: number;
@Output() notify: EventEmitter<string> =
new EventEmitter<string>();
onClick() {
[Link]('clicked!');
[Link] }
}
<td>
<pm-star [rating]='[Link]'> [Link]
</pm-star> <div (click)='onClick()'>
</td> ... stars ...
</div>
Raising an Event (@Output)
[Link] [Link]
@Component({ @Component({
selector: 'pm-products', selector: 'pm-star',
templateURL: './[Link]' templateURL: './[Link]'
}) })
export class ProductListComponent { } export class StarComponent {
@Input() rating: number;
starWidth: number;
@Output() notify: EventEmitter<string> =
new EventEmitter<string>();
onClick() {
[Link]('clicked!');
[Link] }
}
<td>
<pm-star [rating]='[Link]' [Link]
(notify)='onNotify($event)'> <div (click)='onClick()'>
</pm-star> ... stars ...
</td> </div>
Raising an Event (@Output)
[Link] [Link]
@Component({ @Component({
selector: 'pm-products', selector: 'pm-star',
templateURL: './[Link]' templateURL: './[Link]'
}) })
export class ProductListComponent { export class StarComponent {
onNotify(message: string): void { } @Input() rating: number;
} starWidth: number;
@Output() notify: EventEmitter<string> =
new EventEmitter<string>();
onClick() {
[Link]('clicked!');
[Link] }
}
<td>
<pm-star [rating]='[Link]' [Link]
(notify)='onNotify($event)'> <div (click)='onClick()'>
</pm-star> ... stars ...
</td> </div>
Nest-able Component's Public API
Container Component
Template
Nested Component
<pm-star> </pm-star>
Template
Input @Input()
Output @Output()
Class
Class
Checklist: Nested Component
Input decorator
- Attached to a property of any type
- Prefix with @; Suffix with ()
Output decorator
- Attached to a property declared as an
EventEmitter
- Use the generic argument to define the
event payload type
- Use the new keyword to create an
instance of the EventEmitter
- Prefix with @; Suffix with ()
Checklist: Container Component
Use the directive
- Directive name -> nested component's
selector
Use property binding to pass data to the
nested component
Use event binding to respond to events
from the nested component
- Use $event to access the event payload
passed from the nested component
Building a Nested Component
Summary
Using a Nested Component
Passing Data to a Nested Component
Using @Input
Raising an Event from a Nested
Component Using @Output
Application Architecture
Welcome
Component
App Product List
[Link]
Component Component
Star
Component
Product Detail
Product Data Component
Service