Skip to content
Daniel Escalante Perez edited this page May 16, 2024 · 1 revision

Paso 2

Requisitos

En este ejemplo queremos que cuando un usuario seleccione (dando clic) un libro o un autor se muestre el detalle de ese elemento.

Adicionalmente, queremos, en el caso del autor, ver todos los libros de ese autor.

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: author-detail-component.ts y
  • NombremoduloDetailComponent la clase del componente, por ejemplo AuthorDetailComponent .

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

...
import { AuthorDetailComponent } from './author-detail/author-detail.component';
@NgModule({
    imports: [
        ...
    ],
    declarations: [
        AuthorListComponent, 
        AuthorDetailComponent
    ],
   ...
})
export class AuthorModule { }

El nuevo componente AuthorDetailComponent se ocupa de mostrar el detalle del autor que el usuario seleccionó de la lista de autores. Debemos tener claro:

  1. Cómo se envía al AuthorDetailComponent el id del autor que el usuario seleccionó.
  2. Cómo trae la información de ese objeto.
  3. Cómo despliega la información.

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:

/books/:id

/authors/:id

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

...
{
        path: 'authors',
        children: [
            {
                path: 'list',
                component: AuthorListComponent
            },
            {
                path: ':id',
                component: AuthorDetailComponent
            }
        ]
    }
...

Con el path formado por: /authors/:id se asoció el componente AuthorDetailComponent.

Modificación del html del componente listar

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

      <div *ngFor="let author of authors" class="book-card">
        <div class="card p-2 mb-2" style="width: 12rem; height: 23rem">
          <a
            class="card-block text-decoration-none"
            (click)="selectAuthor(author)"
          >
            <img
              class="card-img-top"
              src="{{ author.image }}"
              alt="{{ author.name }}"
            />
            <div class="card-body black-text">
              <h5 class="card-title">{{ author.name }}</h5>
              <p class="card-text">
                {{ author.birthDate }}
              </p>
            </div>
          </a>
        </div>
      </div>

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 AuthorDetailComponent implements OnInit {

    constructor(
        private authorService: AuthorService,
        private route: ActivatedRoute
    ) { }

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

author_id es un atributo de la clase donde 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.

Llamado al API para traer un objeto por id

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

Get /authors/123

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

...
@Injectable()
export class AuthorService {

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

    ...
     getAuthorDetail(id: string): Observable<AuthorDetail> {
       return this.http.get<AuthorDetail>(this.apiUrl + "/" + id);
     }
...
}

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

Vista del componente detalle

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

...
<p class="h3 p-3">Author: {{authorDetail.name}}</p>
...