Introduction
This lab is continuation of the Angular 2 learning series.
We are going to learn the basic building blocks of Angular2 web application which are Components.
Please go through my previous labs on Angular 2 to set up the project and learn Angular 2 easily.
Angular Components
In Angular 2, everything is a component.
Components are the main way we build and specify elements and logic on the page, through both custom elements and attributes that add functionality to our existing components.
What does this mean?
Component Code
- import {Component} from '@angular/core';
-
- @Component({
- selector: 'my-app',
- template: `<h1>Hello {{name}} </h1>`,
- })
-
- export class AppComponent {
- name = 'Angular';
- }
If you analyze component code closely you will see it consists of three portions.
Section 1 - Class
- export class AppComponent {
- name = 'Angular';
- }
Export key word with the class makes this class being used by other components.
Section 2 - Decorator
Here the decorator is @Component which add metadata. This decorator is provided by Angular framework and to use this section 3 is required, meaning we must import that component in appCompnenet class.
- @Component ({
- selector: 'my-app',
- template: `<h1>Hello {{name}} </h1>`,
- })
Component Decorator has several properties which are used to provide a way to add meta data to class.
Above we have used two properties, selector and temperate.
Selector
Selector: ‘my-app’
This property is used to define a section where my-app will be used as directive and the template html will be added to the rendering section of html.
Template
template: `<h1>Hello {{name}} </h1>`
Basically, this is a small piece of html code with backtick character.
Index.html
- <!DOCTYPE html>
- <html>
- <head>
- <title>Angular QuickStart</title>
- <base href="/src/">
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <link rel="stylesheet" href="styles.css">
-
- <!-- Polyfill(s) for older browsers -->
- <script src="/node_modules/core-js/client/shim.min.js"></script>
-
- <script src="/node_modules/zone.js/dist/zone.js"></script>
- <script src="/node_modules/systemjs/dist/system.src.js"></script>
-
- <script src="systemjs.config.js"></script>
- <script>
- System.import('main.js').catch(function(err){ console.error(err); });
- </script>
- </head>
-
- <body>
- <my-app>Loading AppComponent content here ...</my-app>
- </body>
- </html>
At run time <my-app> directive component is replaced by template code when index .html is being rendered.
Result
Section 3 - Angular Component
Component decorator is imported from angular/core to be used as reference to be used further by appComponent class to setup meta data.
- import {Component} from '@angular/core';
templateURL
This is another beautiful property to reference a separate html file with all required capabilities of html. Here you can see the template is html code separated by backtick character. This is inline code.
To use templateUrl, I have added app.component.html to app folder and pointed templateUrl to html.
- import {Component} from '@angular/core';
-
- @Component({
- selector: 'my-app',
- templateUrl: "app/app.component.html"
- })
- export class AppComponent {
- name = 'Angular v2';
- }
Nested Component
Nesting of components meaning using component inside another component. In angular2 nesting of component help to design different functionality very easily.
Let’s take a scenario where students UI needs a search functionality where a text box and button will be there which initiate a search and refresh the students table on page with the search result.
Above is the requirement given to achieve where a search functionality needs to be there on student’s page with text box and button.
To achieve this, I am using the previous example of students list with old project.
Here by taking advantage of angular components we can easily achieve this requirement. We need to create a search component which is placed in students component.
Basically, we are nesting search component with students component which is finally injected into main app component.
Let's see in code.
Students.component.ts
- import {Component, NgZone,OnInit} from '@angular/core'
- import {student Service } from './student.service'
- import { IStudents } from './students'
-
- @Component({
- selector: 'student-list',
- templateUrl: 'app/students/student.component.html',
- styleUrls: ['app/students/students.css']
- })
- export class studentComponenet implements OnInit
- {
- _students: IStudents[];
- constructor(private _studentservice: studentService, private zone: NgZone)
- {
- }
- public LoadStudents(searchtext :string): void {
- this._students = this._studentservice.getStudents();
-
- if (searchtext != "") {
- var _studentList: any[] = [];
-
- this._students.forEach(student => {
- if (student.StudentName.toLowerCase().includes(searchtext)) {
- _studentList.push(student);
- }
- })
- this._students = _studentList;
- }
- }
- public LoadStudentsFromService(): void {
-
- this._studentservice.get("http://localhost:59923/api/Students").subscribe((studentData) => this._students = studentData);
- }
- ngOnInit() {
- this.LoadStudents("");
-
- }
- Onclick(searchtext: string): void {
- this.LoadStudents(searchtext);
-
- }
- getResultCount(): number {
- return this._students.length
- }
- }
Students.components.html
- <search-selector [resultCount]="getResultCount()" (Search)="Onclick($event)"></search-selector>
- <br />
-
- <table class="table">
- <thead>
- <tr>
- <th>
- Student Name
- </th>
- <th>
- Gender
- </th>
- <th>
- Location
- </th>
- <th>
- Date of Joining
- </th>
- </tr>
- </thead>
- <tbody>
- <tr *ngFor="let student of _students">
- <td >{{student.StudentName}}</td>
- <td>{{student.Gender}}</td>
- <td>{{student.Location}}</td>
- <td>{{student.DateOfJoining}}</td>
- </tr>
- </tbody>
- </table>
search.component.ts
- import { Component,Input, Output, EventEmitter } from '@angular/core'
-
- @Component({
- selector: 'search-selector',
- templateUrl:'app/Search/Search.Component.html'
- })
- export class searchComponent
- {
- @Input() resultCount: number=10;
-
- @Output() Search = new EventEmitter<any>();
-
- Onclick(searchtext: string): void {
- this.Search.emit(searchtext);
- }
- }
search.Component.html
- <div class="form-group">
- <div class="md-col-12">
- <input class="form-control" #searchText type="text" placeholder="Search Here" />
- <button type="submit" class="btn btn-default" (click)="Onclick(searchText.value)">
- Search
- </button>
- </div>
- <br />
- <div class="md-col-4">
- <b>Result Count: {{resultCount}} </b>
- </div>
- </div>
I have added four files two type script and two html files above.
In the above file Students.components.html you can see search-selector section above the html for students
- <search-selector [resultCount]="getResultCount()" (Search)="Onclick($event)"></search-selector>
This is how we can register our component for nesting it another component.
Here search component is nested with student component.
Input and Output Properties for Component
You must be wondering what are @input() and @output() properties used above with searchCompoment.
@input (): Property Binding (Parent component to child Component)
@Input decorator binds a property within one component (search component) to receive a value from another component (student component).
For using @input decorator for any property and we need to import Input from angular/core.
- import {Component, Input, Output, EventEmitter} from '@angular/core
Need to decorate the property with @input decorator
- @Input() resultCount: number=10;
In above the result count is the number of records displayed on the child component which is being sent from parent component using input properties.
@Output: Event Binding (Child component To parent Component)
@Output decorator binds a property of a component to send user actions, data from one component (child component) to calling component (parent component). This is one way to pass data from child to parent component
For using @output decorator for any property and we need to import Output from angular/core
- import {Component, Input, Output, EventEmitter} from '@angular/core
- @Output() Search = new EventEmitter<any> ();
-
- Onclick(searchtext: string): void {
- this.Search.emit(searchtext);
Here you can see Search is decorated with @Output and it make it as custom event of EventEmitter class for payload of type any.
This property name becomes custom event name for calling component
- <search-selector [resultCount]="getResultCount()" (Search)="Onclick($event)"></search-selector>
Search becomes a custom event which is bound with click event of button, so whenever search button is clicked from child component which is (search functionality) , it will pass the text from child to parent as parameter and records as per the search text matching result will be displayed and the count will be sent back from parent component to child and web page is being updated.
Final Output
Conclusion
I have used Angular2 services in this article to fetch student’s data from WebAPI and display on the web page. In my next article, I am going to explain services in detail
Keep learning and keep smiling.
Resources and Useful Links
https://angular.io/docs
<<Click here for previous part