Creating and Communicating Between Components
Check code at: https://github.com/wghglory/angular2-fundamental
Creating Our First Data-bound Component
- create events/events-list.component.ts:
import { Component } from '@angular/core'
@Component({
selector: 'events-list',
template: `
Upcoming Angular 2 Events
Event: {{event.name}}
Price: \${{event.price}} //in ts file must use \$ as $!
Date: {{event.date}}
Time: {{event.time}}
Address: {{event.location.address}}, {{event.location.city}}, {{event.location.country}}
`
})
export class EventsListComponent {
event = {
name: 'ngConf 2025',
date: '3/1/2025',
time: '8am',
price: '599',
location: { address: '123 Main St', city: 'Salt Lake City, UT', country: 'USA' }
}
}
- modify app.component.ts:
import { Component } from '@angular/core'
@Component({
selector: 'events-app',
- // template: 'hello world
'
+ template: ' '
})
export class AppComponent {}
- update module:
import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { AppComponent } from './app.component'
+ import { EventsListComponent } from './events/events-list.component'
@NgModule({
imports: [BrowserModule],
+ declarations: [AppComponent, EventsListComponent],
bootstrap: [AppComponent]
})
export class AppModule {}
Using External Templates
- create events-list.component.html as template:
Upcoming Angular 2 Events
Event: {{event.name}}
Price: ${{event.price}}
Date: {{event.date}}
Time: {{event.time}}
Address: {{event.location.address}}, {{event.location.city}}, {{event.location.country}}
- modify events-list.component.ts using templateUrl instead of template:
import { Component } from '@angular/core'
@Component({
selector: 'events-list',
- // template: ``
+ templateUrl: 'app/events/events-list.component.html' //relative to index.html
})
export class EventsListComponent {
event = {
name: 'ngConf 2025',
date: '3/1/2025',
time: '8am',
price: '599',
location: { address: '123 Main St', city: 'Salt Lake City, UT', country: 'USA' }
}
}
Components Interaction
1. Communicating with Child Components Using @Input (Parent pass data to child)
I want to create a address component as a child component. The parent component, events-list, will pass the event object to the child. To get this done:
- child component needs import Input from angular/core
- parent template uses the child selector, and [child object name] = "parent"
- create child component events-address.component.ts
//child component, talk with parent events-list.component.ts
import {Component,Input} from '@angular/core'
@Component({
selector: 'events-address',
template: '{{address.address}},{{address.city}},{{address.country}}'
})
export class EventsAddressComponent{
@Input() address:any //define address object
}
- modify parent component template, [address] is child object name, "event.location" is parent data
Upcoming Angular 2 Events
Event: {{event.name}}
Price: ${{event.price}}
Date: {{event.date}}
Time: {{event.time}}
- import child component to app.module
import { EventsAddressComponent } from './events/events-address.component'
@NgModule({
declarations: [AppComponent, EventsListComponent, EventsAddressComponent],
})
2. Communicating with Parent Components Using @Output and EventEmitter (child pass data to parent)
- child component "events-address.component.ts":
- import Output, EventEmitter
- define a variable accepting EventEmitter
- define buttonClick
- the EventEmitter variable emit any data from child component
//child component, talk with parent events-list.component.ts
import {Component, Output, EventEmitter} from '@angular/core'
@Component({
selector: 'events-address',
template: ''
})
export class EventsAddressComponent{
@Output() myclick = new EventEmitter()
buttonClick(){
this.myclick.emit('I am from child component, should pass data to parent component')
}
}
- parent Component "events-list.component.ts":
-
update template: (the EventEmitter variable name defined in child component) = "randomFuncInParent($event)"
-
define random function in parent component class
export class EventsListComponent { clickWithAnyName(dataFromChild){ alert(dataFromChild) } }
3. Using Template Variables To Interact with Child Components (parent access to child data, easier than method 2)
- child component events-address.component.ts define public property and method
//child component, talk with parent events-list.component.ts
@Component({
selector: 'events-address',
template: ''
})
export class EventsAddressComponent {
//use template variable to interact with child public method/property: parent accesses child data
author:string = 'Guanghui Wang' //child public property
getAuthor(){
alert(this.author)
}
}
- access child component data from parent component template's childPointer variable
{{childPointer.author}}
Styling Components
By default, style scope is current component: the class defined below works only in current component, any other component applied same class won't work.
Global css can be placed in styles.css
@Component({
template: ``,
styles: [`.mybutton{background:purple;}`]
})
export class EventsAddressComponent {}
Create Navbar
create nav/nav.component.ts and its template nav.component.html, then export component into module.
import {Component} from '@angular/core'
@Component({
selector: 'nav-bar',
templateUrl: 'app/nav/nav.component.html',
styles: [`
.nav.navbar-nav {font-size:15px;}
#searchForm {margin-right:100px;}
@media(max-width:1200px) {#searchForm {display:none;}}
`]
})
export class NavBarComponent { }