View Class 11 Demo Online Here
Today we will learn:
- How to Create Components from scratch
- How to Create Components using the CLI
- How to Style our Components
- The Basics of Data-Binding
- The Basics of Event-Binding
- How to Use Two-Way-Binding
- How to Use String Interpolation
- The Basics of Structural Directives
- The Basics of Attribute Directives
-
Component: A component is a section or feature of your application. Every component has its own template, style, and logic. The benefit is that they are reusable and controllable.
-
Data-Binding: Data-Binding is how we automatically update our pages template when our application state changes.
-
Event-Binding: Event-Binding is a one-way connection from the view/template to the data source/logic.
-
Two-Way-Binding: Two-Way-Binding is when we connect the view/template to the source/logic, and when either of them changes, they both update.
- Note: This begins with a new project w/ bootstrap hooked up.
box/box.component.ts file:
-
Right-click on the "app" folder and create a new folder title "box".
-
Inside the "box" folder, create a new file title "box.component.ts".
-
Export a class titled "BoxComponent" (all words caps).
-
Add the
Component({})
decorator. (Make sure to import this from "@angular/core"). -
Add the configuration for the component by adding a "selector" property that points to a string value "app-box".
-
Add another property in the "Component" decorator titled "templateUrl" that is a key to the value of "./box.component.html".
import { Component } from "@angular/core";
@Component({
selector: "app-box",
templateUrl: "./box.component.html"
})
export class BoxComponent {}
box/box.component.html file:
-
Create the "box.component.html" file inside the "box" folder.
-
Add a
<div class="card mt-3 box">
with a<p class="text-center">I am a box!</p>
inside.
<div class="card mt-3 box">
<p class="text-center">I am a box!</p>
</div>
app.module.ts file:
- Note: To use this component in our app, we must import it and add it to the declarations array in our main "app.modules.ts" file.
import { NgModule } from "@angular/core";
import { FormsModule } from "@angular/forms";
import { BrowserModule } from "@angular/platform-browser";
import { AppComponent } from "./app.component";
import { BoxComponent } from "./box/box.component";
@NgModule({
declarations: [AppComponent, BoxComponent],
imports: [BrowserModule, FormsModule],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
app.component.html file:
-
First, create a container, row, and column that takes up the full width. Put an
<h1>
inside. -
Since we chose the string "app-box" for our selector, we can use that tag inside of our HTML.
<div class="container mt-5">
<div class="row justify-content-center">
<div class="col-xs-12">
<h1>Angular Boxes</h1>
<app-box></app-boxes>
</div>
</div>
</div>
Terminal:
- Create a new component using the CLI that will hold multiple "app-box" components. Title it "boxes"
ng g c boxes
- Delete the test file.
boxes/boxes.component.html file:
- Create three instances of the "app-box" component using the
<app-box></app-box>
tags.
<app-box></app-box>
<app-box></app-box>
<app-box></app-box>
app.component.html file:
- Change the tag to render the
<app-boxes>
instead of a singular<app-box>
.
app.component.css file:
- Style the
<h1>
tag to be "red", have a size of "4rem" and a margin-bottom of ".5em".
h1 {
color: crimson;
font-size: 4rem;
margin-bottom: 0.5em;
}
box/box.component.css file:
-
Create the "box.component.css" file inside the "box" folder.
-
Style the ".box" class by adding a background-color, color, font-size, height, and flex properties.
.box {
background-color: saddlebrown;
color: white;
font-size: 1.5rem;
height: 200px;
display: flex;
align-items: center;
justify-content: center;
}
box/box.component.ts file:
- Link your newly created styles by adding another property in the "Component({})" Decorator.
@Component({
selector: 'app-box',
templateUrl: './box.component.html',
styleUrls: ['./box.component.css']
})
box/box.component.ts file:
- Create two new variables:
boxNumber = 2;
andisEmpty = false;
box/box.component.html file:
- Output these variables in the box markup inside two paragraph elements. (Walkthrough the ternary operator slowly)!
<p class="text-center">I am box number {{ boxNumber }}!</p>
<p>I am {{ isEmpty ? "empty" : "full" }}.</p>
boxes/boxes.component.ts file:
-
Create a new boolean variable:
canOpenMoreBoxes = false
. -
Inside the "ngOnInit", create a timeout function that sets the "canOpenMoreBoxes" boolean variable to true after 3 seconds.
export class BoxesComponent implements OnInit {
canOpenMoreBoxes = false;
constructor() {}
ngOnInit(): void {
setTimeout(() => {
this.canOpenMoreBoxes = true;
}, 3000);
}
}
boxes/boxes.component.html file:
- Create a button above the boxes that allows us to create a new box. (This button should be disabled if "canOpenMoreBoxes" is false).
<button class="btn btn-primary" [disabled]="!canOpenMoreBoxes">
Open New Box
</button>
boxes/boxes.component.ts file:
-
Create another variable:
boxMockText = "You should open a box man."
. -
Create a function that changes the "boxMockText" whenever you open a new box. Name this function accordingly.
export class BoxesComponent implements OnInit {
canOpenMoreBoxes = false;
boxMockText = "You haven't opened a box in a while";
constructor() {}
ngOnInit(): void {
setTimeout(() => {
this.canOpenMoreBoxes = true;
}, 3000);
}
onOpenBox() {
this.boxMockText = "You just opened another box!";
}
}
boxes/boxes.component.html file:
-
Create a paragraph tag below the button that outputs the "boxMockText" variable string.
-
Add a
(click)
event listener on the button that calls our "onOpenBox()" function. -
Remove the "boxNumber" paragraph.
<button
class="btn btn-primary"
[disabled]="!canOpenMoreBoxes"
(click)="onOpenBox()"
>
Open New Box
</button>
<p>{{ boxMockText }}</p>
<hr />
<!-- . . . -->
boxes/boxes.component.ts file:
-
Create a new variable:
boxName = "Default Box";
-
Inside the "onOpenBox()" function, change the string to a template literal (``) and add in the "boxName" variable.
boxName = "Default Box"
// . . .
onOpenBox() {
this.boxMockText = `You just opened a box called: ${this.boxName}`
}
boxes/boxes.component.html file:
-
Create a label and input that binds to the "boxName" variable.
-
Note: Make sure you have the { FormsModule } imported in your application.
<label for="boxName">Box Name:</label>
<input type="text" class="form-control mb-3" [(ngModel)]="boxName" />
<button
class="btn btn-primary"
[disabled]="!canOpenMoreBoxes"
(click)="onOpenBox()"
>
Open New Box
</button>
<!-- . . . -->
boxes/boxes.component.html file:
- Add an
*ngIf
directive to the{{ boxMockText }}
paragraph and bind it to a boolean varaible "haveOpenedABox".
<p *ngIf="haveOpenedABox">{{boxMockText}}</p>
boxes/boxes.component.ts file:
-
Create the "haveOpenedABox" variable and set it to initialize as false.
-
In the "onOpenBox()" function, set the "haveOpenedABox" to true.
haveOpenedABox = false;
// . . .
onOpenBox() {
// . . .
haveOpenedABox = true;
}
box/box.component.ts file:
-
Create a constructor. Inside, set our "isEmpty" variable to be true half the time and false the other half using math.
-
Create a function that gets a color depending on our "isEmpty" variable.
constructor() {
this.isEmpty = Math.random() > 0.5;
}
getColor() {
return this.isEmpty === true ? 'red' : 'green';
}
box/box.component.html file:
- Using the "isEmpty" variable, display different text with a different class depending on the value.
<p>
I am
<span [ngStyle]="{ color: getColor() }">{{ isEmpty ? "empty" : "full" }}</span
>.
</p>
- We can do this in a different way using the
[ngClass]
Directive. We will show this by placing a "ngClass" attribute on the card div.
<div class="card" [ngClass]="{ emptyBox: isEmpty === true }"></div>
box/box.component.css file:
- Create style for the ".emptyBox" class.
.emptyBox {
height: 100px;
font-size: 1rem;
opacity: 0.75;
}
boxes/boxes.component.ts file:
-
Create an array called "boxes" and fill it with dummy data.
-
Inside the "onOpenBox()" function, push the current boxName to the "boxes" array.
export class BoxesComponent implements OnInit {
canOpenMoreBoxes = false;
hasOpenedABox = false;
boxMockText = "";
boxName = "";
boxes = ["Box 1", "Box 2", "Box 3"];
// . . .
onOpenBox() {
this.hasOpenedABox = true;
this.boxes.push(this.boxName);
this.boxMockText = `You just opened a box called: "${this.boxName}"!`;
}
}
boxes/boxes.component.html file:
-
Remove all but on
<app-box>
tag. -
Place an "*ngFor" loop on the
<app-box>
that loops over all the boxes in the "boxes" array.
<app-box *ngFor="let box of boxes"></app-box>
-
Generate a new Angular project (with strict mode disabled). Name it "angular-basics-exercise".
-
Manually create a component called "article".
-
In the article component, create variables
title: string = "Whatever you want"
andcontent: string = "Some content goes here"
. -
Use string interpolation to output the title in an h1 element and the content in a paragraph element. (Note: you can google 'lorem ipsum generator ' to generate dummy text).
-
Display the article component by adding it in the main "app.component.html" file.
-
In the article component, add another variable:
isTechRelated: boolean = true
. -
Use "ngStyle" to change the background of the h1 element to blue when "isTechrelated" is true; Otherwise, it should be yellow.
-
Push your local repository to GitHub, call the repo 'angular-basics-exercise'.
Bonus: In the article component, create a button with the content "change isTechRelated". (Use event binding to reverse the variable "isTechRelated" value whenever a user clicks the button).
Bonus: In the article component, use "ngIf" to display a paragraph element with content "Tech Related" when the "isTechRelated" is true. When false, use the ng-template element to display "Not Tech Related".