Angular: miscellaneous goods

@Component is a decorator function that specifies the Angular metadata for the component.

Styles and stylesheets identified in @Component metadata are scoped to that specific component. The heroes.component.css styles apply only to the HeroesComponent and don't affect the outer HTML or the HTML in any other component.


@Injectable() services

Notice that the new service imports the Angular Injectable symbol and annotates the class with the @Injectable() decorator.

The @Injectable() decorator tells Angular that this service might itself have injected dependencies. It doesn't have dependencies now but it will soon. Whether it does or it doesn't, it's good practice to keep the decorator.

Observable.subscribe() is the critical difference.
The previous version assigns an array of heroes to the component's heroes property. The assignment occurs synchronously, as if the server could return heroes instantly or the browser could freeze the UI while it waited for the server's response.
That won't work when the HeroService is actually making requests of a remote server.
The new version waits for the Observable to emit the array of heroes— which could happen now or several minutes from now. Then subscribe passes the emitted array to the callback, which sets the component's heroes property.
This asynchronous approach will work when the HeroService requests heroes from the server.


Add routes

Routes tell the router which view to display when a user clicks a link or pastes a URL into the browser address bar.
A typical Angular Route has two properties:
  1. path: a string that matches the URL in the browser address bar.
  2. component: the component that the router should create when navigating to this route.

RouterModule.forRoot()

You first must initialize the router and start it listening for browser location changes.
Add RouterModule to the @NgModule.imports array and configure it with the routes in one step by calling RouterModule.forRoot() within the imports array, like this:
imports: [ RouterModule.forRoot(routes) ],

The method is called forRoot() because you configure the router at the application's root level. The forRoot() method supplies the service providers and directives needed for routing, and performs the initial navigation based on the current browser URL.

Add RouterOutlet

Open the AppComponent template replace the <app-heroes> element with a <router-outlet> element.










src/app/app.component.html (router-outlet)

<h1>{{title}}</h1>
<router-outlet></router-outlet>
<app-messages></app-messages>

You removed <app-heroes> because you will only display the HeroesComponent when the user navigates to it.
The <router-outlet> tells the router where to display routed views.
The RouterOutlet is one of the router directives that became available to the AppComponent because AppModule imports AppRoutingModule which exported RouterModule.

Users shouldn't have to paste a route URL into the address bar. They should be able to click a link to navigate.
Add a <nav> element and, within that, an anchor element that, when clicked, triggers navigation to the HeroesComponent. The revised AppComponent template looks like this:








src/app/app.component.html (heroes RouterLink)

<h1>{{title}}</h1>
<nav>
  <a routerLink="/heroes">Heroes</a>
</nav>
<router-outlet></router-outlet>
<app-messages></app-messages>

routerLink attribute is set to "/heroes", the string that the router matches to the route to HeroesComponent. The routerLink is the selector for the RouterLink directive that turns user clicks into router navigations. It's another of the public directives in the RouterModule.
The browser refreshes and displays the app title and heroes link, but not the heroes list.
Click the link. The address bar updates to /heroes and the list of heroes appears.
Make this and future navigation links look better by adding private CSS styles to app.component.css as listed in the final code review below.

Enable HTTP services

HttpClient is Angular's mechanism for communicating with a remote server over HTTP.
To make HttpClient available everywhere in the app,

Http methods return one value

All HttpClient methods return an RxJS Observable of something.
HTTP is a request/response protocol. You make a request, it returns a single response.
In general, an Observable can return multiple values over time. An Observable from HttpClientalways emits a single value and then completes, never to emit again.
This particular HttpClient.get call returns an Observable<Hero[]>, literally "an observable of hero arrays". In practice, it will only return a single hero array.

HttpClient.get returns response data

HttpClient.get returns the body of the response as an untyped JSON object by default. Applying the optional type specifier, <Hero[]> , gives you a typed result object.
The shape of the JSON data is determined by the server's data API. The Tour of Heroes data API returns the hero data as an array.


If you neglect to subscribe(), the service will not send the delete request to the server! As a rule, an Observable does nothing until something subscribes!



AsyncPipe

As expected, the *ngFor repeats hero objects.
Look closely and you'll see that the *ngFor iterates over a list called heroes$, not heroes.
<li *ngFor="let hero of heroes$ | async" >

The $ is a convention that indicates heroes$ is an Observable, not an array.
The *ngFor can't do anything with an Observable. But there's also a pipe character (|) followed by async, which identifies Angular's AsyncPipe.
The AsyncPipe subscribes to an Observable automatically so you won't have to do so in the component class.

Không có nhận xét nào:

StaticImage

  import React , { useEffect , useRef } from "react" import { StaticImage } from "gatsby-plugin-image" impor...