diff --git a/aio/content/tutorial/toh-pt4.en.md b/aio/content/tutorial/toh-pt4.en.md new file mode 100644 index 0000000000..6c7bb8cbfe --- /dev/null +++ b/aio/content/tutorial/toh-pt4.en.md @@ -0,0 +1,446 @@ +# Add services + +The Tour of Heroes `HeroesComponent` is currently getting and displaying fake data. + +After the refactoring in this tutorial, `HeroesComponent` will be lean and focused on supporting the view. +It will also be easier to unit-test with a mock service. + +
+ + For the sample app that this page describes, see the . + +
+ + +## Why services + +Components shouldn't fetch or save data directly and they certainly shouldn't knowingly present fake data. +They should focus on presenting data and delegate data access to a service. + +In this tutorial, you'll create a `HeroService` that all application classes can use to get heroes. +Instead of creating that service with the [`new` keyword](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new), +you'll rely on Angular [*dependency injection*](guide/dependency-injection) +to inject it into the `HeroesComponent` constructor. + +Services are a great way to share information among classes that _don't know each other_. +You'll create a `MessageService` and inject it in two places. + +1. Inject in HeroService, which uses the service to send a message. +2. Inject in MessagesComponent, which displays that message, and also displays the ID +when the user clicks a hero. + + +## Create the `HeroService` + +Using the Angular CLI, create a service called `hero`. + + + ng generate service hero + + +The command generates a skeleton `HeroService` class in `src/app/hero.service.ts` as follows: + + + + +### `@Injectable()` services + +Notice that the new service imports the Angular `Injectable` symbol and annotates +the class with the `@Injectable()` decorator. This marks the class as one that participates in the _dependency injection system_. The `HeroService` class is going to provide an injectable service, and it can also have its own injected dependencies. +It doesn't have any dependencies yet, but [it will soon](#inject-message-service). + +The `@Injectable()` decorator accepts a metadata object for the service, the same way the `@Component()` decorator did for your component classes. + +### Get hero data + +The `HeroService` could get hero data from anywhere—a web service, local storage, or a mock data source. + +Removing data access from components means you can change your mind about the implementation anytime, without touching any components. +They don't know how the service works. + +The implementation in _this_ tutorial will continue to deliver _mock heroes_. + +Import the `Hero` and `HEROES`. + + + + +Add a `getHeroes` method to return the _mock heroes_. + + + + +{@a provide} +## Provide the `HeroService` + +You must make the `HeroService` available to the dependency injection system +before Angular can _inject_ it into the `HeroesComponent` 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. + +To make sure that the `HeroService` can provide this service, register it +with the _injector_, which is the object that is responsible for choosing +and injecting the provider where the app requires it. + +By default, the Angular CLI command `ng generate service` registers a provider with the _root injector_ for your service by including provider metadata, that is `providedIn: 'root'` in the `@Injectable()` decorator. + +``` +@Injectable({ + providedIn: 'root', +}) +``` + +When you provide the service at the root level, Angular creates a single, shared instance of `HeroService` and injects into any class that asks for it. +Registering the provider in the `@Injectable` metadata also allows Angular to optimize an app by removing the service if it turns out not to be used after all. + +
+ +To learn more about providers, see the [Providers section](guide/providers). +To learn more about injectors, see the [Dependency Injection guide](guide/dependency-injection). + +
+ +The `HeroService` is now ready to plug into the `HeroesComponent`. + +
+ +This is an interim code sample that will allow you to provide and use the `HeroService`. At this point, the code will differ from the `HeroService` in the ["final code review"](#final-code-review). + +
+ + +## Update `HeroesComponent` + +Open the `HeroesComponent` class file. + +Delete the `HEROES` import, because you won't need that anymore. +Import the `HeroService` instead. + + + + +Replace the definition of the `heroes` property with a simple declaration. + + + + +{@a inject} + +### Inject the `HeroService` + +Add a private `heroService` parameter of type `HeroService` to the constructor. + + + + +The parameter simultaneously defines a private `heroService` property and identifies it as a `HeroService` injection site. + +When Angular creates a `HeroesComponent`, the [Dependency Injection](guide/dependency-injection) system +sets the `heroService` parameter to the singleton instance of `HeroService`. + +### Add `getHeroes()` + +Create a method to retrieve the heroes from the service. + + + + +{@a oninit} + +### Call it in `ngOnInit()` + +While you could call `getHeroes()` in the constructor, that's not the best practice. + +Reserve the constructor for simple initialization such as wiring constructor parameters to properties. +The constructor shouldn't _do anything_. +It certainly shouldn't call a function that makes HTTP requests to a remote server as a _real_ data service would. + +Instead, call `getHeroes()` inside the [*ngOnInit lifecycle hook*](guide/lifecycle-hooks) and +let Angular call `ngOnInit()` at an appropriate time _after_ constructing a `HeroesComponent` instance. + + + + +### See it run + +After the browser refreshes, the app should run as before, +showing a list of heroes and a hero detail view when you click on a hero name. + +## Observable data + +The `HeroService.getHeroes()` method has a _synchronous signature_, +which implies that the `HeroService` can fetch heroes synchronously. +The `HeroesComponent` consumes the `getHeroes()` result +as if heroes could be fetched synchronously. + + + + +This will not work in a real app. +You're getting away with it now because the service currently returns _mock heroes_. +But soon the app will fetch heroes from a remote server, +which is an inherently _asynchronous_ operation. + +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. + +In this tutorial, `HeroService.getHeroes()` will return an `Observable` +because it will eventually use the Angular `HttpClient.get` method to fetch the heroes +and [`HttpClient.get()` returns an `Observable`](guide/http). + +### Observable `HeroService` + +`Observable` is one of the key classes in the [RxJS library](http://reactivex.io/rxjs/). + +In a [later tutorial on HTTP](tutorial/toh-pt6), you'll learn that Angular's `HttpClient` methods return RxJS `Observable`s. +In this tutorial, you'll simulate getting data from the server with the RxJS `of()` function. + +Open the `HeroService` file and import the `Observable` and `of` symbols from RxJS. + + + + +Replace the `getHeroes()` method with the following: + + + +`of(HEROES)` returns an `Observable` that emits _a single value_, the array of mock heroes. + +
+ +In the [HTTP tutorial](tutorial/toh-pt6), you'll call `HttpClient.get()` which also returns an `Observable` that emits _a single value_, an array of heroes from the body of the HTTP response. + +
+ +### Subscribe in `HeroesComponent` + +The `HeroService.getHeroes` method used to return a `Hero[]`. +Now it returns an `Observable`. + +You'll have to adjust to that difference in `HeroesComponent`. + +Find the `getHeroes` method and replace it with the following code +(shown side-by-side with the previous version for comparison) + + + + + + + + + + + +`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. +The `subscribe()` method 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. + +## Show messages + +This section guides you through the following: + +* adding a `MessagesComponent` that displays app messages at the bottom of the screen +* creating an injectable, app-wide `MessageService` for sending messages to be displayed +* injecting `MessageService` into the `HeroService` +* displaying a message when `HeroService` fetches heroes successfully + +### Create `MessagesComponent` + +Use the CLI to create the `MessagesComponent`. + + + ng generate component messages + + +The CLI creates the component files in the `src/app/messages` folder and declares the `MessagesComponent` in `AppModule`. + +Modify the `AppComponent` template to display the generated `MessagesComponent`. + + + + +You should see the default paragraph from `MessagesComponent` at the bottom of the page. + +### Create the `MessageService` + +Use the CLI to create the `MessageService` in `src/app`. + + + ng generate service message + + +Open `MessageService` and replace its contents with the following. + + + + +The service exposes its cache of `messages` and two methods: one to `add()` a message to the cache and another to `clear()` the cache. + +{@a inject-message-service} +### Inject it into the `HeroService` + +In `HeroService`, import the `MessageService`. + + + + +Modify the constructor with a parameter that declares a private `messageService` property. +Angular will inject the singleton `MessageService` into that property +when it creates the `HeroService`. + + + + +
+ +This is a typical "*service-in-service*" scenario: +you inject the `MessageService` into the `HeroService` which is injected into the `HeroesComponent`. + +
+ +### Send a message from `HeroService` + +Modify the `getHeroes()` method to send a message when the heroes are fetched. + + + + +### Display the message from `HeroService` + +The `MessagesComponent` should display all messages, +including the message sent by the `HeroService` when it fetches heroes. + +Open `MessagesComponent` and import the `MessageService`. + + + + +Modify the constructor with a parameter that declares a **public** `messageService` property. +Angular will inject the singleton `MessageService` into that property +when it creates the `MessagesComponent`. + + + + +The `messageService` property **must be public** because you're going to bind to it in the template. + +
+ +Angular only binds to _public_ component properties. + +
+ +### Bind to the `MessageService` + +Replace the CLI-generated `MessagesComponent` template with the following. + + + + +This template binds directly to the component's `messageService`. + +* The `*ngIf` only displays the messages area if there are messages to show. + + +* An `*ngFor` presents the list of messages in repeated `
` elements. + + +* An Angular [event binding](guide/event-binding) binds the button's click event +to `MessageService.clear()`. + +The messages will look better when you add the private CSS styles to `messages.component.css` +as listed in one of the ["final code review"](#final-code-review) tabs below. + +## Add additional messages to hero service + +The following example shows how to send and display a message each time the user clicks on +a hero, showing a history of the user's selections. This will be helpful when you get to the +next section on [Routing](tutorial/toh-pt5). + + + + +The browser refreshes and the page displays the list of heroes. +Refresh the browser to see the list of heroes, and scroll to the bottom to see the +messages from the HeroService. Each time you click a hero, a new message appears to record +the selection. Use the "clear" button to clear the message history. + +{@a final-code-review} + +## Final code review + +Here are the code files discussed on this page. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## Summary + +* You refactored data access to the `HeroService` class. +* You registered the `HeroService` as the _provider_ of its service at the root level so that it can be injected anywhere in the app. +* You used [Angular Dependency Injection](guide/dependency-injection) to inject it into a component. +* You gave the `HeroService` _get data_ method an asynchronous signature. +* You discovered `Observable` and the RxJS _Observable_ library. +* You used RxJS `of()` to return an observable of mock heroes (`Observable`). +* The component's `ngOnInit` lifecycle hook calls the `HeroService` method, not the constructor. +* You created a `MessageService` for loosely-coupled communication between classes. +* The `HeroService` injected into a component is created with another injected service, + `MessageService`. diff --git a/aio/content/tutorial/toh-pt4.md b/aio/content/tutorial/toh-pt4.md index 6c7bb8cbfe..6c1b76174b 100644 --- a/aio/content/tutorial/toh-pt4.md +++ b/aio/content/tutorial/toh-pt4.md @@ -1,87 +1,88 @@ -# Add services +# Agregar servicios -The Tour of Heroes `HeroesComponent` is currently getting and displaying fake data. +El `HeroesComponent` de Tour de los Heroes actualmente está obteniendo y mostrando datos simulados. -After the refactoring in this tutorial, `HeroesComponent` will be lean and focused on supporting the view. -It will also be easier to unit-test with a mock service. +Después de la refactorización en este tutorial, `HeroesComponent` será sencillo y se centrará en apoyar la vista. +También será más fácil realizar pruebas unitarias con un servicio simulado.
- For the sample app that this page describes, see the . + Para ver la aplicación de ejemplo que describe esta página, consulte el .
+## Por qué servicios -## Why services +Los componentes no deberían buscar ni guardar datos directamente y, desde luego, no deberían presentar a sabiendas datos simulados. +Deben centrarse en presentar datos y delegar el acceso a los datos a un servicio. -Components shouldn't fetch or save data directly and they certainly shouldn't knowingly present fake data. -They should focus on presenting data and delegate data access to a service. +En este tutorial, crearás un `HeroService` que todas las clases de aplicación pueden usar para obtener héroes. +En lugar de crear ese servicio con la [palabra clave `new`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new), +confiará en la [*inyección de dependencia*](guide/dependency-injection) de Angular +para inyectarlo en el constructor `HeroesComponent`. -In this tutorial, you'll create a `HeroService` that all application classes can use to get heroes. -Instead of creating that service with the [`new` keyword](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new), -you'll rely on Angular [*dependency injection*](guide/dependency-injection) -to inject it into the `HeroesComponent` constructor. +Los servicios son una excelente manera de compartir información entre clases que no se _conocen entre sí_. +Creará un `MessageService` y lo inyectará en dos lugares. -Services are a great way to share information among classes that _don't know each other_. -You'll create a `MessageService` and inject it in two places. - -1. Inject in HeroService, which uses the service to send a message. -2. Inject in MessagesComponent, which displays that message, and also displays the ID -when the user clicks a hero. +1. Inyecte en HeroService, que utiliza el servicio para enviar un mensaje. +2. Inyecte en MessagesComponent, que muestra ese mensaje, y también muestra la ID +cuando el usuario hace clic en un héroe. -## Create the `HeroService` +## Crear el `HeroService` -Using the Angular CLI, create a service called `hero`. +Usando la CLI Angular, cree un servicio llamado `hero`. ng generate service hero -The command generates a skeleton `HeroService` class in `src/app/hero.service.ts` as follows: +Este comando generará un archivo base `HeroService` en `src/app/hero.service.ts` de la siguiente manera: -### `@Injectable()` services +### Servicio `@Injectable()` -Notice that the new service imports the Angular `Injectable` symbol and annotates -the class with the `@Injectable()` decorator. This marks the class as one that participates in the _dependency injection system_. The `HeroService` class is going to provide an injectable service, and it can also have its own injected dependencies. -It doesn't have any dependencies yet, but [it will soon](#inject-message-service). +Observe que el símbolo Inyectable de Angular se importa en el archivo generado, anotando la clase como decorador `@Injectable()`. +Esto marca a la clase como participante en el sistema de inyección de dependencia. La clase `HeroService` proporcionará servicios inyectables y puede tener dependencias. +Aún no hay dependencias, [estará pronto](#inject-message-service). -The `@Injectable()` decorator accepts a metadata object for the service, the same way the `@Component()` decorator did for your component classes. +El decorador `@Injectable()` acepta el objeto de metadatos de un servicio de la misma manera que el decorador `@Component()` para las clases de componentes. -### Get hero data +### Obtener datos del héroe -The `HeroService` could get hero data from anywhere—a web service, local storage, or a mock data source. -Removing data access from components means you can change your mind about the implementation anytime, without touching any components. -They don't know how the service works. +El `HeroService` podría obtener datos de héroes desde cualquier lugar— un servicio web, almacenamiento local o una fuente de datos simulada. -The implementation in _this_ tutorial will continue to deliver _mock heroes_. + +Eliminar el acceso a datos de los componentes significa que puede cambiar de opinión acerca de la implementación en cualquier momento, sin tocar ningún componente. +No saben cómo funciona el servicio. -Import the `Hero` and `HEROES`. +La implementación en este tutorial continuará entregando _héroes simulados_. + +Importar `Hero` and `HEROES`. -Add a `getHeroes` method to return the _mock heroes_. +Agregue el método `getHeroes` y devuelva los _héroes simulados_. {@a provide} -## Provide the `HeroService` +## Proporcionar el `HeroService` -You must make the `HeroService` available to the dependency injection system -before Angular can _inject_ it into the `HeroesComponent` 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. +Debe poner el `HeroService` a disposición del sistema de inyección de dependencias. +antes de que Angular pueda inyectarlo en el 'Componente de héroes' al registrar un proveedor. Un proveedor es algo que puede crear o prestar un servicio; en este caso, crea una instancia de la clase `HeroService` para proporcionar el servicio. -To make sure that the `HeroService` can provide this service, register it -with the _injector_, which is the object that is responsible for choosing -and injecting the provider where the app requires it. +Para asegurarse de que el `HeroService` pueda proporcionar este servicio, regístrelo +con el _inyector_, que es el objeto responsable de elegir +e inyectando el proveedor donde la aplicación lo requiere. -By default, the Angular CLI command `ng generate service` registers a provider with the _root injector_ for your service by including provider metadata, that is `providedIn: 'root'` in the `@Injectable()` decorator. +Por defecto, el comando Angular CLI `ng generate service` registra a un proveedor con el inyector raíz para su servicio al incluir los metadatos del proveedor, que se proporcionan en el decorador `@Injectable() `. ``` @Injectable({ @@ -89,320 +90,323 @@ By default, the Angular CLI command `ng generate service` registers a provider w }) ``` -When you provide the service at the root level, Angular creates a single, shared instance of `HeroService` and injects into any class that asks for it. -Registering the provider in the `@Injectable` metadata also allows Angular to optimize an app by removing the service if it turns out not to be used after all. +Cuando proporciona el servicio en el nivel raíz, Angular crea una única instancia compartida de `HeroService` e inyecta en cualquier clase que lo solicite. +El registro del proveedor en los metadatos `@Injectable` también le permite a Angular optimizar una aplicación eliminando el servicio si resulta que no se usará después de todo.
-To learn more about providers, see the [Providers section](guide/providers). -To learn more about injectors, see the [Dependency Injection guide](guide/dependency-injection). +Para obtener más información sobre los proveedores, consulte la [Sección de proveedores](guide/providers). +Para obtener más información sobre los inyectores, consulte la [Guía de inyección de dependencia](guide/dependency-injection).
- -The `HeroService` is now ready to plug into the `HeroesComponent`. +El `HeroService` ahora está listo para conectarse al `HeroesComponent`.
-This is an interim code sample that will allow you to provide and use the `HeroService`. At this point, the code will differ from the `HeroService` in the ["final code review"](#final-code-review). +Este es un ejemplo de código provisional que le permitirá proporcionar y usar el `HeroService`. En este punto, el código diferirá del `HeroService` en la [" revisión final del código "](#final-code-review).
+
-## Update `HeroesComponent` +Si desea obtener más información sobre _proveedores_, consulte [Proveedores](guide/providers). -Open the `HeroesComponent` class file. +
-Delete the `HEROES` import, because you won't need that anymore. -Import the `HeroService` instead. +## Actualizar `HeroesComponent` + +Abra el archivo de clase `HeroesComponent`. + +Elimine la importación `HEROES`, porque ya no la necesitará. +Importa el `HeroService` en su lugar. -Replace the definition of the `heroes` property with a simple declaration. +Reemplace la definición de la propiedad `heroes` con una simple declaración. {@a inject} -### Inject the `HeroService` +### Inyectar el `HeroService` -Add a private `heroService` parameter of type `HeroService` to the constructor. +Agregue un parámetro privado `heroService` de tipo `HeroService` al constructor. -The parameter simultaneously defines a private `heroService` property and identifies it as a `HeroService` injection site. +El parámetro define simultáneamente una propiedad privada `heroService` y la identifica como un sitio de inyección `HeroService`. -When Angular creates a `HeroesComponent`, the [Dependency Injection](guide/dependency-injection) system -sets the `heroService` parameter to the singleton instance of `HeroService`. +Cuando Angular crea un `HeroesComponent`, el sistema [Inyección de dependencia](guide/dependency-injection) establece el parámetro `heroService` en la instancia única de `HeroService`. -### Add `getHeroes()` +### Añadir `getHeroes()` -Create a method to retrieve the heroes from the service. +Crea un método para recuperar a los héroes del servicio {@a oninit} -### Call it in `ngOnInit()` +### Llamarlo en `ngOnInit()` -While you could call `getHeroes()` in the constructor, that's not the best practice. +Si bien podría llamar a `getHeroes()` en el constructor, esa no es la mejor práctica. -Reserve the constructor for simple initialization such as wiring constructor parameters to properties. -The constructor shouldn't _do anything_. -It certainly shouldn't call a function that makes HTTP requests to a remote server as a _real_ data service would. +Reserve el constructor para una inicialización simple, como conectar los parámetros del constructor a las propiedades. +El constructor no debe _hacer nada_. +Ciertamente no debería llamar a una función que realiza solicitudes HTTP a un servidor remoto como lo haría un servicio de datos _real_. -Instead, call `getHeroes()` inside the [*ngOnInit lifecycle hook*](guide/lifecycle-hooks) and -let Angular call `ngOnInit()` at an appropriate time _after_ constructing a `HeroesComponent` instance. +En su lugar, llame a `getHeroes()` dentro del [*ngOnInit lifecycle hook*](guide/lifecycle-hooks) (gancho del ciclo de vida) y +deje que Angular llame a `ngOnInit()` en el momento apropiado _después_ de construir una instancia de `HeroesComponent`. -### See it run +### Verlo correr -After the browser refreshes, the app should run as before, -showing a list of heroes and a hero detail view when you click on a hero name. +Después de que el navegador se actualice, la aplicación debería ejecutarse como antes, +mostrando una lista de héroes y una vista detallada de héroe cuando haces clic en el nombre de un héroe. -## Observable data +## Datos observables -The `HeroService.getHeroes()` method has a _synchronous signature_, -which implies that the `HeroService` can fetch heroes synchronously. -The `HeroesComponent` consumes the `getHeroes()` result -as if heroes could be fetched synchronously. +El método `HeroService.getHeroes()` tiene una firma sincrónica, +lo que implica que el `HeroService` puede buscar héroes sincrónicamente. +El `HeroesComponent` consume el resultado `getHeroes()` +como si los héroes pudieran ser recuperados sincrónicamente. -This will not work in a real app. -You're getting away with it now because the service currently returns _mock heroes_. -But soon the app will fetch heroes from a remote server, -which is an inherently _asynchronous_ operation. +Esto no funcionará en una aplicación real. +Ahora te saldrás con la tuya porque el servicio actualmente devuelve _héroes simulados_. +Pero pronto la aplicación buscará héroes de un servidor remoto, +que es una operación inherentemente _asincrónica_. -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. +El `HeroService` debe esperar a que el servidor responda, +`getHeroes()` no puede regresar inmediatamente con los datos del héroe, +y el navegador no se bloqueará mientras el servicio espere. -`HeroService.getHeroes()` must have an _asynchronous signature_ of some kind. +`HeroService.getHeroes()` debe tener una firma asíncrona de algún tipo. -In this tutorial, `HeroService.getHeroes()` will return an `Observable` -because it will eventually use the Angular `HttpClient.get` method to fetch the heroes -and [`HttpClient.get()` returns an `Observable`](guide/http). +En este tutorial, `HeroService.getHeroes()` devolverá un `Observable` +porque eventualmente usará el método angular `HttpClient.get` para buscar a los héroes y [`HttpClient.get()` devuelve un `Observable`](guide/http). ### Observable `HeroService` -`Observable` is one of the key classes in the [RxJS library](http://reactivex.io/rxjs/). +`Observable` es una de las clases clave en la [biblioteca RxJS] (http://reactivex.io/rxjs/). -In a [later tutorial on HTTP](tutorial/toh-pt6), you'll learn that Angular's `HttpClient` methods return RxJS `Observable`s. -In this tutorial, you'll simulate getting data from the server with the RxJS `of()` function. +En un [tutorial posterior sobre HTTP](tutorial/toh-pt6), aprenderá que los métodos `HttpClient` de Angular devuelven RxJS `Observable`s. +En este tutorial, simulará obtener datos del servidor con la función RxJS `of()`. -Open the `HeroService` file and import the `Observable` and `of` symbols from RxJS. +Abra el archivo `HeroService` e importe los símbolos `Observable` y `of` de RxJS. -Replace the `getHeroes()` method with the following: +Reemplace el método `getHeroes()` con lo siguiente: -`of(HEROES)` returns an `Observable` that emits _a single value_, the array of mock heroes. +`of (HEROES)` devuelve un `Observable ` que emite _un valor único_, el conjunto de héroes simulados. -
+
-In the [HTTP tutorial](tutorial/toh-pt6), you'll call `HttpClient.get()` which also returns an `Observable` that emits _a single value_, an array of heroes from the body of the HTTP response. +En el [tutorial HTTP](tutorial/toh-pt6), llamará a `HttpClient.get ()` que también devuelve un `Observable ` que emite _un valor único_, una matriz de héroes del cuerpo de la respuesta HTTP.
-### Subscribe in `HeroesComponent` +### Suscríbirse en `HeroesComponent` -The `HeroService.getHeroes` method used to return a `Hero[]`. -Now it returns an `Observable`. +El método `HeroService.getHeroes` utilizado para devolver un `Hero[]`. +Ahora devuelve un `Observable `. -You'll have to adjust to that difference in `HeroesComponent`. +Tendrás que ajustarte a esa diferencia en `HeroesComponent`. -Find the `getHeroes` method and replace it with the following code -(shown side-by-side with the previous version for comparison) +Encuentre el método `getHeroes` y reemplácelo con el siguiente código +(Al lado de la versión anterior para comparar) - - -`Observable.subscribe()` is the critical difference. +`Observable.subscribe()` es la diferencia crítica. -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. +La versión anterior asigna una variedad de héroes a la propiedad 'heroes' del componente. +La asignación ocurre _sincrónicamente_, como si el servidor pudiera devolver héroes al instante +o el navegador podría congelar la interfaz de usuario mientras esperaba la respuesta del servidor. -That _won't work_ when the `HeroService` is actually making requests of a remote server. +Eso _no funcionará_ cuando el `HeroService` realmente está haciendo solicitudes a un servidor remoto. -The new version waits for the `Observable` to emit the array of heroes—which -could happen now or several minutes from now. -The `subscribe()` method passes the emitted array to the callback, -which sets the component's `heroes` property. +La nueva versión espera a que el 'Observable' emita una serie de héroes,— +que podría suceder ahora o varios minutos a partir de ahora. +El método `subscribe()` pasa el arreglo emitida a la devolución de llamada, +que establece la propiedad 'heroes' del componente. -This asynchronous approach _will work_ when -the `HeroService` requests heroes from the server. +Este enfoque asincrónico funcionará cuando +el `HeroService` solicite héroes del servidor. -## Show messages +## Mostrar mensajes -This section guides you through the following: +Esta sección lo guía a través de lo siguiente: -* adding a `MessagesComponent` that displays app messages at the bottom of the screen -* creating an injectable, app-wide `MessageService` for sending messages to be displayed -* injecting `MessageService` into the `HeroService` -* displaying a message when `HeroService` fetches heroes successfully +* agregando un `MessagesComponent` que muestra los mensajes de la aplicación en la parte inferior de la pantalla +* crear un `MessageService` inyectable para toda la aplicación para enviar mensajes que se mostrarán +* inyectando `MessageService` en el `HeroService` +* mostrando un mensaje cuando `HeroService` busca héroes con éxito -### Create `MessagesComponent` - -Use the CLI to create the `MessagesComponent`. +### Crear `MessagesComponent` +Use la CLI para crear el `MessagesComponent`. ng generate component messages -The CLI creates the component files in the `src/app/messages` folder and declares the `MessagesComponent` in `AppModule`. -Modify the `AppComponent` template to display the generated `MessagesComponent`. +La CLI crea los archivos componentes en la carpeta `src/app/messages` y declara el `MessagesComponent` en `AppModule`. + +Modifique la plantilla `AppComponent` para mostrar el `MessagesComponent` generado. -You should see the default paragraph from `MessagesComponent` at the bottom of the page. +Debería ver el párrafo predeterminado de `MessagesComponent` en la parte inferior de la página. -### Create the `MessageService` +### Crear el `MessageService` -Use the CLI to create the `MessageService` in `src/app`. +Use la CLI para crear el `MessageService` en `src/app`. ng generate service message -Open `MessageService` and replace its contents with the following. +Abra `MessageService` y reemplace su contenido con lo siguiente. -The service exposes its cache of `messages` and two methods: one to `add()` a message to the cache and another to `clear()` the cache. +El servicio expone su caché de `mensajes` y dos métodos: uno para `agregar()` un mensaje al caché y otro para `borrar()` el caché. {@a inject-message-service} -### Inject it into the `HeroService` +### Inyectar en el `HeroService` + +En `HeroService`, importe el `MessageService`. -In `HeroService`, import the `MessageService`. -Modify the constructor with a parameter that declares a private `messageService` property. -Angular will inject the singleton `MessageService` into that property -when it creates the `HeroService`. +Modifique el constructor con un parámetro que declare una propiedad privada `messageService`. +Angular inyectará el singleton `MessageService` en esa propiedad +cuando crea el `HeroService`. -
+
-This is a typical "*service-in-service*" scenario: -you inject the `MessageService` into the `HeroService` which is injected into the `HeroesComponent`. +Este es un escenario típico de "*servicio en servicio*": +inyecta el `MessageService` en el `HeroService` que se inyecta en el `HeroesComponent`.
-### Send a message from `HeroService` +### Enviar un mensaje desde `HeroService` -Modify the `getHeroes()` method to send a message when the heroes are fetched. +Modifique el método `getHeroes()` para enviar un mensaje cuando se busquen los héroes. -### Display the message from `HeroService` +### Mostrar el mensaje de `HeroService` -The `MessagesComponent` should display all messages, -including the message sent by the `HeroService` when it fetches heroes. +El `MessagesComponent` debería mostrar todos los mensajes, +incluido el mensaje enviado por el `HeroService` cuando busca héroes. -Open `MessagesComponent` and import the `MessageService`. +Abra `MessagesComponent` e importe el `MessageService` -Modify the constructor with a parameter that declares a **public** `messageService` property. -Angular will inject the singleton `MessageService` into that property -when it creates the `MessagesComponent`. +Modifique el constructor con un parámetro que declare una propiedad `messageService` **publica**. +Angular inyectará el único `MessageService` en esa propiedad +cuando crea el `MessagesComponent`. -The `messageService` property **must be public** because you're going to bind to it in the template. +La propiedad `messageService` **debe ser pública** porque la vinculará en la plantilla.
-Angular only binds to _public_ component properties. +Angular solo se une a las propiedades _publicas_ del componente .
-### Bind to the `MessageService` - -Replace the CLI-generated `MessagesComponent` template with the following. +### Enlazar al `MessageService` +Reemplace la plantilla `MessagesComponent` generada por CLI con lo siguiente. +  -This template binds directly to the component's `messageService`. +Esta plantilla se une directamente al componente `messageService` del componente. -* The `*ngIf` only displays the messages area if there are messages to show. +* `*NgIf` solo muestra el área de mensajes si hay mensajes para mostrar. -* An `*ngFor` presents the list of messages in repeated `
` elements. +* Un `*ngFor` presenta la lista de mensajes en elementos repetidos`
`. -* An Angular [event binding](guide/event-binding) binds the button's click event -to `MessageService.clear()`. +* Un [enlace de evento](guide/template-syntax) en angular une el evento de clic del botón +a `MessageService.clear ()`. -The messages will look better when you add the private CSS styles to `messages.component.css` -as listed in one of the ["final code review"](#final-code-review) tabs below. +Los mensajes se verán mejor cuando agregue los estilos CSS privados a `messages.component.css` +como se indica en una de las pestañas ["revisión de código final"](#final-code-review) a continuación. -## Add additional messages to hero service +## Agregar mensajes adicionales al servicio de héroe -The following example shows how to send and display a message each time the user clicks on -a hero, showing a history of the user's selections. This will be helpful when you get to the -next section on [Routing](tutorial/toh-pt5). +El siguiente ejemplo muestra cómo enviar y mostrar un mensaje cada vez que el usuario hace clic en +un héroe, que muestra un historial de las selecciones del usuario. Esto será útil cuando llegues a +siguiente sección sobre [Enrutamiento](tutorial/toh-pt5). -The browser refreshes and the page displays the list of heroes. -Refresh the browser to see the list of heroes, and scroll to the bottom to see the -messages from the HeroService. Each time you click a hero, a new message appears to record -the selection. Use the "clear" button to clear the message history. +El navegador se actualizará y la página mostrará la lista de héroes. +Actualiza el navegador para ver la lista de héroes y desplázate hacia abajo para ver +mensajes del HeroService. Cada vez que haces clic en un héroe, aparece un nuevo mensaje para grabar +la selección. Use el botón "borrar" para borrar el historial de mensajes. {@a final-code-review} -## Final code review +## Revisión final del código -Here are the code files discussed on this page. +Aquí están los archivos de código discutidos en esta página. - - @@ -432,15 +436,16 @@ Here are the code files discussed on this page. -## Summary +## Resumen -* You refactored data access to the `HeroService` class. -* You registered the `HeroService` as the _provider_ of its service at the root level so that it can be injected anywhere in the app. -* You used [Angular Dependency Injection](guide/dependency-injection) to inject it into a component. -* You gave the `HeroService` _get data_ method an asynchronous signature. -* You discovered `Observable` and the RxJS _Observable_ library. -* You used RxJS `of()` to return an observable of mock heroes (`Observable`). -* The component's `ngOnInit` lifecycle hook calls the `HeroService` method, not the constructor. -* You created a `MessageService` for loosely-coupled communication between classes. -* The `HeroService` injected into a component is created with another injected service, - `MessageService`. +* Refactorizó el acceso a datos a la clase `HeroService`. +* Registro el `HeroService` como el _proveedor_ de su servicio en el nivel raíz para que pueda inyectarse en cualquier lugar de la aplicación. +* Usó la [Inyección de dependencia angular](guide/dependency-injection) para inyectarlo en un componente. +* Le dio al `HeroService` el método _get data_ una firma asincrónica. +* Descubrio `Observable` y la biblioteca RxJS _Observable_. +* Usó RxJS `of ()` para devolver un observable de héroes simulados (`Observable `). +* El lifecycle hook (gancho del ciclo de vida) `ngOnInit` del componente llama al método `HeroService`, no al constructor. +* Creó un `MessageService` para una comunicación débilmente acoplada entre clases. +* El `HeroService` inyectado en un componente se crea con otro servicio inyectado, + `MessageService`. + \ No newline at end of file