paso2 - keblato/TutorialesTalleres-Angular GitHub Wiki

Paso 2

Checkout del paso 2

Comience por realizar el checkout del paso-1b del front. Si no encuentra la rama del paso1b significa que cuando clonó el proyecto no clonó esta rama, en ese caso por favor clone la rama.

git checkout -f paso-1b

Actualice, preferiblemente en una ventana de comandos, la instalación de paquetes con:

npm install

Requerimientos de ver el detalle de un elemento

En este ejemplo queremos que cuando un usuario seleccione (dando clic) un libro, un autor o una editorial se muestre el detalle de ese elemento. Las explicaciones de esta parte están en Componente Detalle

Adicionalmente, queremos, en el caso del autor ver todos los libros de ese autor, de la editorial, ver todos los libros que esa editorial edita y del libro, ver todos los libros excepto el que se seleccionó. Las explicaciones de esta parte están en Componente Listar libros parametrizado.

Componente Detalle

Creación del componente

Cada uno de los módulos va a tener un nuevo componente detalle, que por convención de nombramiento llamaremos:

  • nombremodulo-detail-component.ts, el archivo que lo contiene, por ejemplo: editorial-detail-component.ts y
  • NombremoduloDetailComponent la clase del componente, por ejemplo EditorialDetailComponent .

El componente detalle debe declararse en el módulo que corresponde. Por ejemplo, en el módulo EditorialModule (editorial.module.ts) tenemos, el siguiente fragmento solo para mostrar la declaración del nuevo componente EditorialDetailComponent:

...
import { EditorialDetailComponent } from './editorial-detail/editorial-detail.component';
@NgModule({
    imports: [
        ...
    ],
    declarations: [
        EditorialListComponent, 
        EditorialDetailComponent
    ],
   ...
})
export class EditorialModule { }

El siguiente diagrama muestra los elementos más importantes que intervienen en este diseño. Note que en azul están las clases que representan los json (Los Dtos del Back) que son recibidos por el front cuando se hacen los llamados al API-REST. Estas clases son básicamente las mismas, solo que en typescript, a las clases DTO que tenemos en el back de java.

El nuevo componente EditorialDetailComponent se ocupa de mostrar el detalle de la editorial que el usuario seleccionó de la lista de editoriales. Debemos tener claro:

  1. Cómo se envía al EditorialDetailComponent el id de la editorial que el usuario seleccionó.
  2. Cómo trae la información de ese objeto.
  3. Cómo despliega la información.
Volver a Inicio

Paso del id al componente detalle

Definición de las nuevas rutas para los detalles

Lo primero que se debe hacer es definir las rutas de navegación para llegar a los detalles. Esto se hace en el módulo AppRoutingModule. Las rutas que vamosa definir son:

/editorials/:id

/books/:id

/authors/:id

Esto se hace de la siguiente manera en el arreglo routes de AppRoutingModule:

...
{
        path: 'editorials',
        children: [
            {
                path: 'list',
                component: EditorialListComponent
            },
            {
                path: ':id',
                component: EditorialDetailComponent
            }
        ]
    }
...

Con el path formado por: /editorials/:id se asoció el componente EditorialDetailComponent.

Volver a Inicio

Modificación del html del componente listar

Para enviar el id de la editorial desde la lista de editoriales, debemos asignarle el valor al router-link de la ruta del detalle. El siguiente fragmento del archivo editorials-list.componente.html muestra cómo se escribe:

 <tr *ngFor = "let editorial of editorials">
                    <td style="cursor: pointer;">
                        <dd class="figure-caption" routerLink="/editorials/{{editorial.id}}">{{editorial.name}}</dd>
                    </td>
 </tr>

El componente detalle obtiene el id

Para que el componente detalle obtenga el id, en el método ngInit() debemos recuperarlo a partir de la ruta activa ActivatedRoute que debe ser inyectada al componente en el constructor para poder utilizarla. EL fragmento siguiente muestra cómo:

...
export class EditorialDetailComponent implements OnInit {

    constructor(
        private editorialService: EditorialService,
        private route: ActivatedRoute
    ) { }

   editorial_id: number; 
...
    ngOnInit() {
        this.editorial_id = +this.route.snapshot.paramMap.get('id');
        ...
    }
...

editorial_id es un atributo de la clase onde dejaremos el valor del id que venía en el path. EL método para obtener el id del path es: this.route.snapshot.paramMap.get('id'). El símbolo + antes del método lo que hace es convertir el id de string a number.

Volver a Inicio

Llamado al API para traer un objeto por id

En el servicio EditorialService asociado con el componente, agregamos un método para realizar el:

Get /editorials/123

Este método utiliza el servicio Angular HttpClient, para esto lo inyecta en el constructor de EditorialService. EL método getEditorialDetail recibe de parámetro el id de la editorial y declara el resultado de http.get como un Observable.

...
@Injectable()
export class EditorialService {

    ...
    constructor(private http: HttpClient) { }

   ...
    getEditorialDetail(editorialId): Observable<EditorialDetail> {
        return this.http.get<EditorialDetail>(API_URL + editorials + '/' + editorialId);
    }
...
}

El componente EditorialDetailComponent define un método getEditorialDetail que se suscribe a este método definido en el servicio y obtiene el objeto del detalle y lo deja en una variable editorialDetail que será visible por el template.

Volver a Inicio

Vista del componente detalle

El template del componente detalle utiliza la variable editorialDetail definida en el componente EditorialDetailComponent para obtener los valores. El siguiente fragmento muestra como se obtiene el nombre:

...
<p class="h3 p-3">Editorial: {{editorialDetail.name}}</p>
...

En el caso del componente para el detalle de un author AuthorDetailComponent tenemos el siguiente fragmento del template que utiliza la variable authorDetail definida en el componente:

...
        <p class="h3 p-3">{{authorDetail.name}}<p> 
        <div class="row">
            <div class="col-md-3">
                <div class="thumb">
                    <img class="img-fluid" src='{{authorDetail.image}}' alt="{{authorDetail.image}}" />   
                </div>
            </div>
            <div class="col-md-3">
                <dl>     
                    <dt>Bio</dt>
                    <dd>{{authorDetail.description}}</dd>
                    <dt>BirthDay</dt>
                    <dd>{{authorDetail.birthDate| date:'MM/dd/yyyy'}}</dd>
                </dl>
            </div>           
        </div>
...

Note que en este ejemplo estamos manejando las fechas como string y lo único que estamos haciendo es formatéandolas como fechas. Para el caso del atributo birthDate usamos el filtro: date:'MM/dd/yyyy'.

Volver a Inicio
⚠️ **GitHub.com Fallback** ⚠️