The Languages Editor
The application now has a basic title. Next you will create a new component to display language information and place that component in the application shell.
Create the languages component
Using the Angular CLI, generate a new component named languages.
ng generate component languages
The CLI creates a new folder,
src/app/languages/
and generates the three files of the LanguagesComponent
.
The
LangaugesComponent
class file is as follows:
You always import the
Component
symbol from the Angular core library and annotate the component class with @Component
.@Component
is a decorator function that specifies the Angular metadata for the component.
The CLI generated three metadata properties:
selector
— the component's CSS element selectortemplateUrl
— the location of the component's template file.styleUrls
— the location of the component's private CSS styles.
The CSS element selector,
'app-languages'
, matches the name of the HTML element that identifies this component within a parent component's template.
The
ngOnInit
is a lifecycle hook Angular calls ngOnInit
shortly after creating a component. It's a good place to put initialization logic.
Always
export
the component class so you can import
it elsewhere ... like in the AppM
odule
.Add a language property
Add a
language
property to the LanguagesComponent
for a language named "C Sharp."language = 'C Sharp';
Show the language
Open the
languages.component.html
template file. Delete the default text generated by the Angular CLI and replace it with a data binding to the new language
property.{{language}}
Show the LanguagesComponent view
To display the
LanguagesComponent
, you must add it to the template of the shell AppComponent
.
Remember that
app-languages
is the element selector for the LanguagesComponent
. So add an <app-heroes>
element to the AppComponent
template file, just below the title.<h1>{{title}}</h1>
<app-languages></app-languages>
Assuming that the CLI
ng serve
command is still running, the browser should refresh and display both the application title and the language name.Create a Language class
Create a Language class in its own file in the
src/app
folder. Give it id
and name
properties.export class Language {
id: number;
name: string;
}
Return to the
LanguagesComponent
class and import the Language
class.
Refactor the component's language property to be of type
Language
. Initialize it with an id
of 1
and the name C Sharp
.
The revised
LanguagesComponent
class file should look like this:import { Component, OnInit } from '@angular/core';
import { Language } from '../language';
@Component({
selector: 'app-languages',
templateUrl: './heroes.component.html',
styleUrls: ['./heroes.component.css']
})
export class Languagesomponent implements OnInit {
language: Language = {
id: 1,
name: 'C Sharp'
};
constructor() { }
ngOnInit() {
}
}
The page no longer displays properly because you changed the language from a string to an object.
Show the language object
Update the binding in the template to announce the language's name and show both
id
and name
in a details layout like this:<h2>{{ language.name }} Details</h2>
<div><span>id: </span>{{language.id}}</div>
<div><span>name: </span>{{language.name}}</div>
The browser refreshes and display's the language's information.
Format with the UppercasePipe
Modify the
language.name
binding like this.<h2>{{ language.name | uppercase }} Details</h2>
The browser refreshes and now the language's name is displayed in capital letters.
The word
uppercase
in the interpolation binding, right after the pipe operator ( | ), activates the built-in UppercasePipe
.
Pipes are a good way to format strings, currency amounts, dates and other display data. Angular ships with several built-in pipes and you can create your own.
Edit the language
Users should be able to edit the language name in an
<input>
textbox.
The textbox should both display the language's
name
property and update that property as the user types. That means data flow from the component class out to the screen and from the screen back to the class.
To automate that data flow, setup a two-way data binding between the
<input>
form element and the language.name
property.Two-way binding
Refactor the details area in the
LanguagesComponent
template so it looks like this:<div>
<label>name:
<input [(ngModel)]="languages.name" placeholder="name">
</label>
</div>
[(ngModel)] is Angular's two-way data binding syntax.
Here it binds the
language.name
property to the HTML textbox so that data can flow in both directions: from the language.name
property to the textbox, and from the textbox back to the language.name
.The missing FormsModule
Notice that the app stopped working when you added
[(ngModel)]
.
To see the error, open the browser development tools and look in the console for a message like
Template parse errors:
Can't bind to 'ngModel' since it isn't a known property of 'input'.
Although
ngModel
is a valid Angular directive, it isn't available by default.
It belongs to the optional
FormsModule
and you must opt-in to using it.AppModule
Angular needs to know how the pieces of your application fit together and what other files and libraries the app requires. This information is called metadata
Some of the metadata is in the
@Component
decorators that you added to your component classes. Other critical metadata is in @NgModule
decorators.
The most important
@NgModule
decorator annotates the top-level AppModule class.
The Angular CLI generated an
AppModule
class in src/app/app.module.ts
when it created the project. This is where you opt-in to the FormsModule
.Import FormsModule
Open
AppModule
(app.module.ts
) and import the FormsModule
symbol from the @angular/forms
library.import { FormsModule } from '@angular/forms'; // <-- NgModel lives here
Then add
FormsModule
to the @NgModule
metadata's imports
array, which contains a list of external modules that the app needs.imports: [
BrowserModule,
FormsModule
],
When the browser refreshes, the app should work again. You can edit the language's name and see the changes reflected immediately in the
<h2>
above the textbox.Declare LanguagesComponent
Every component must be declared in exactly one NgModule.
You didn't declare the
LanguagesComponent
. So why did the application work?
It worked because the Angular CLI declared LanguagesComponent in the
AppModule
when it generated that component.
Open
src/app/app.module.ts
and find LanguagesComponent imported near the top.import { LanguagesComponent } from './languages/languages.component';
The LanguagesComponentis declared in the
@NgModule.declarations
array.declarations: [
AppComponent,
LanguagesComponent
],
Note that
AppModule
declares both application components, AppComponent
and LanguagesComponent
.Summary
- You used the CLI to create a second LanguagesComponent.
- You displayed the LanguagesComponent by adding it to the
AppComponent
shell. - You applied the
UppercasePipe
to format the name. - You used two-way data binding with the
ngModel
directive. - You learned about the
AppModule
. - You imported the
FormsModule
in theAppModule
so that Angular would recognize and apply thengModel
directive. - You learned the importance of declaring components in the
AppModule
and appreciated that the CLI declared it for you.
Comments
Post a Comment