Passing Data to Sub Components in Angular
Let’s say we have a list of products we need to display and we want a sub component to be responsible for displaying each product. We want it to look something like this …
Parent component
So, our parent component is as follows to begin with …
import { Component } from "angular2/core";
import { Product } from "./product";
@Component({
selector: "my-app",
template: `
<ul>
<li *ngFor="#p of products">
TODO: reference our sub component
</li>
</ul>
`,
styles: [
`
ul {
list-style: none;
}
`
]
})
export class AppComponent {
products: Product[];
constructor() {
this.products = [
{ code: "P001", name: "Chai", quantityRemaining: 1 },
{ code: "P002", name: "Tofu", quantityRemaining: 112 },
{ code: "P003", name: "Pavlova", quantityRemaining: 53 }
];
}
}
… Line 8 iterates through the products and line 9 is ready to reference a sub component.
Sub component
Our sub component is as follows …
import { Component } from "angular2/core";
import { Product } from "./product";
@Component({
selector: "product-item",
template: `
<div class="product-wrapper">
<div>
<span class="product-code">{{ product.code }}</span
><span class="product-name">{{ product.name }}</span>
</div>
<span class="product-quantity">{{ product.quantityRemaining }}</span>
remaining
</div>
`,
styles: [
`
.product-wrapper {
padding-top: 6px;
padding-bottom: 6px;
}
.product-code {
padding-right: 6px;
border-right: 1px solid #d4ced6;
}
.product-name {
font-weight: bold;
padding-left: 6px;
}
.product-quantity {
padding-right: 6px;
}
`
]
})
export class ProductItemComponent {}
Lines 9 and 11 reference a product object that, at the moment, the sub component isn’t wired up to …
Wiring them up
First we need to reference the sub component from the parent component by adding an import statement …
import { ProductItemComponent } from "./productItem.component";
… and also referencing the selector in the template.
However, we need to pass the product when we call the sub component. First we need to use the Input annotation in the sub component to declare that a property called product can be passed in …
import {Component, Input} from 'angular2/core';
...
export class ProductItemComponent {
@Input() product: Product;
}
In the parent component, we can then set the product property when we reference the sub component.
<li *ngFor="#p of products">
<product-item [product]="p"></product-item>
</li>
That’s it - nice an simple! Here’s the full listing of the parent and sub components …
import { Component } from "angular2/core";
import { ProductItemComponent } from "./productItem.component";
import { Product } from "./product";
@Component({
selector: "my-app",
directives: [ProductItemComponent],
template: `
<ul>
<li *ngFor="#p of products">
<product-item [product]="p"></product-item>
</li>
</ul>
`,
styles: [
`
ul {
list-style: none;
}
`
]
})
export class AppComponent {
products: Product[];
constructor() {
this.products = [
{ code: "P001", name: "Chai", quantityRemaining: 1 },
{ code: "P002", name: "Tofu", quantityRemaining: 112 },
{ code: "P003", name: "Pavlova", quantityRemaining: 53 }
];
}
}