QuickStart
Step 1. Set up the Development Environment
|
|
Step 2. Create a new project
|
|
Step 3: Serve the application
|
|
Step 4: Edit your first Angular component
|
|
|
|
Project file review
|
|
Tutorial
|
|
Angular components
Components are the fundamental building blocks of Angular applications. They display data on the screen, listen for user input, and take action based on that input.
|
|
Create a new component
create a new component to display hero information and place that component in the application shell.
|
|
|
|
|
|
@Component is a decorator function that specifies the Angular metadata for the component. The metadata properties selector is the component’s CSS element selector.
The CSS element selector, 'app-heroes', 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 AppModule.
|
|
The double curly braces are Angular’s interpolation binding syntax. Remember that app-heroes is the element selector for the HeroesComponent. So add an <app-heroes> element to the AppComponent template file
|
|
The word uppercase in the interpolation binding, right after the pipe operator ( | ), activates the built-in UppercasePipe.
[(ngModel)] is Angular’s two-way data binding syntax.
Here it binds the hero.name property to the HTML textbox so that data can flow in both directions: from the hero.name property to the textbox, and from the textbox back to the hero.name.
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
|
|
Some of the metadata is in the @Component decorators that you added to your component classes. Other critical metadata is in @NgModule decorators.
The @NgModule metadata’s imports array contains a list of external modules that the app needs.
Every component must be declared in exactly one NgModule. Note that AppModule declares both application components, AppComponent and HeroesComponent.
Display a Heroes List
|
|
Add the click event handler.
Class binding
Event binding ( (event) )
Hide empty details with *ngIf
|
|
The *ngFor is Angular’s repeater directive. It repeats the host element for each element in a list.
Class binding syntax start with the prefix class, optionally followed by a dot (.) and the name of a CSS class: [class.class-name]. The Angular class binding makes it easy to add and remove a CSS class conditionally. Just add [class.some-css-class]="some-condition" to the element you want to style.
The parentheses around click tell Angular to listen for the <li> element’s click event. When the user clicks in the <li>, Angular executes the onSelect(hero) expression.
onSelect() is a HeroesComponent method that you’re about to write.
After the browser refreshes, the list of names reappears. The details area is blank because of *ngIf will be false. Click a hero and its details appear.
|
|
Master/Detail Components
Keeping all features in one component as the application grows will not be maintainable. You’ll want to split up large components into smaller sub-components, each focused on a specific task or workflow.
|
|
Add the @Input() hero property
|
|
The hero property must be an Input property, annotated with the @Input() decorator, because the external HeroesComponent will bind to it
|
|
property binding
The two components will have a parent/child relationship. The parent HeroesComponentwill control the child HeroDetailComponent by sending it a new hero to display whenever the user selects a hero from the list.
You won’t change the HeroesComponent class but you will change its template.
|
|
[hero]="selectedHero" is an Angular property binding.
It’s a one way data binding from the selectedHero property of the HeroesComponent to the hero property of the target element, which maps to the hero property of the HeroDetailComponent.
Now when the user clicks a hero in the list, the selectedHero changes. When the selectedHero changes, the property binding updates hero and the HeroDetailComponentdisplays the new hero.
Services
Services are a great way to share information among classes that don’t know each other.
Create the HeroService
|
|
Annotates the class with the @Injectable() decorator. This marks the class as one that participates in the dependency injection system.
The @Injectable() decorator accepts a metadata object for the service, the same way the @Component() decorator did for your component classes.
The HeroService could get hero data from anywhere—a web service, local storage, or a mock data source.
Provide the HeroService
You must make the HeroService available to the dependency injection system before Angular can inject it into the HeroesComponent. You do this by registering a provider. A provider is something that can create or deliver a service; in this case, it instantiates the HeroService class to provide the service.
By default, the Angular CLI command ng generate service registers a provider with the root injector for your service .
If you need to, you can register providers at different levels: in the HeroesComponent, in the AppComponent, in the AppModule. For instance, you could have told the CLI to provide the service at the module level automatically by appending --module=app.
|
|
Observable data
The HeroService must wait for the server to respond, getHeroes() cannot return immediately with hero data, and the browser will not block while the service waits. HeroService.getHeroes() must have an asynchronous signature of some kind. It can take a callback. It could return a Promise. It could return an Observable. HttpClient.get() returns an Observable.
Observable is one of the key classes in the RxJS library.
Angular’s HttpClient methods return RxJS Observables.
Getting data from the server with the RxJS of() function.
Inject MessageSerice into the HeroService
This is a typical “service-in-service” scenario: you inject the MessageService into the HeroService which is injected into the HeroesComponent.
|
|
Update HeroesComponent
- Import the
HeroService - Add a private
heroServiceparameter of typeHeroServiceto the constructor. The parameter simultaneously defines a privateheroServiceproperty and identifies it as aHeroServiceinjection site. - Add
getHeroes(), create this function to retrieve the heroes from the service. - Call it in
ngOnInit. You could callgetHeroes()in the constructor, that’s not the best practice. Reserve the constructor for simple initialization such as wiring constructor parameters to properties. It certainly shouldn’t call a function that makes HTTP requests to a remote server as a real data service would. Let Angular callngOnInitat an appropriate time after constructing aHeroesComponentinstance. - The
HeroService.getHeroesmethod returns anObservable<Hero[]>. The newgetHeroesmethod waits for theObservableto emit the array of heroes. Thensubscribepasses the emitted array to the callback, which sets the component’sheroesproperty.
|
|
Create MessagesComponent
|
|
|
|
Create the MessageService
|
|
|
|
|
|
The messageService property must be public because you’re about to bind to it in the template. Angular only binds to public component properties.
|
|
Routing
Add the AppRoutingModule
An Angular best practice is to load and configure the router in a separate.
|
|
--flat puts the file in src/app instead of its own folder. --module=app tells the CLI to register it in the imports array of the AppModule.
The fundamentals of Angular
Class binding
Event binding ( (event) )link
Pipes
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.