Crear un componente secundario e interactuar con él
Nuestro código base creció en los pasos anteriores. Ahora, tomémonos un minuto para refactorizar nuestro componente Bear List (Lista de osos) en varios componentes más pequeños. Migraremos el código de mosaicos de osos a un nuevo componente.
Cómo crear el componente Bear Tile (Mosaico de oso)
- En VS Code, haga clic con el botón secundario en la carpeta
lwc
y, luego, en SFDX: Create Lightning Web Component (Crear componente web Lightning). - Asigne el nombre
bearTile
al componente. - Abra
bearList.html
y corte todo el código entre<!-- Start bear tile -->
y<!-- End bear tile -->
. - Pegue el código entre las etiquetas
template
debearTile.html
. Una vez hecho esto,bearTile.html
debería verse así.<template> <lightning-card title={bear.Name} class="bear-tile"> <div class="slds-var-p-horizontal_small"> <div class="slds-media"> <div class="slds-media__figure"> <img src={appResources.bearSilhouette} alt="Bear profile" class="bear-silhouette"/> </div> <div class="slds-media__body"> <p class="slds-var-m-bottom_xx-small">{bear.Sex__c}</p> <p class="slds-var-m-bottom_xx-small">{bear.Age__c} years old</p> <p class="slds-var-m-bottom_xx-small">{bear.Height__c} cm</p> <p class="slds-var-m-bottom_xx-small">{bear.Weight__c} Kg</p> </div> </div> </div> </lightning-card> </template>
- Sustituya el contenido de
bearTile.js
por:import { LightningElement, api } from 'lwc'; import ursusResources from '@salesforce/resourceUrl/ursus_park'; export default class BearTile extends LightningElement { @api bear; appResources = { bearSilhouette: `${ursusResources}/standing-bear-silhouette.png`, }; }
Agregamos la propiedadbear
decorada con@api
. Esto expone a la propiedadbear
a cualquier componente superior. - Elimine
bearList.css
. - Cree un nuevo archivo
bearTile.css
en el directoriobearTile
y pegue el siguiente código en el archivo.:host { --sds-c-card-color-background: linear-gradient(180deg, rgba(255,255,255,1) 80%, #fae8d2 100%); } .bear-tile { display: block; border: 1px solid #d2955d; border-radius: .25rem; background-color: #fae8d2; } .bear-silhouette { height: 100px; }
- Abra
bearList.html
y sustituya el contenido entre los comentarios<!-- Start bear tile -->
y<!-- End bear tile -->
por<c-bear-tile bear={bear}></c-bear-tile>
. Una vez hecho esto,bearList.html
debería verse así.<template> <lightning-card title="Bears" icon-name="utility:animal_and_nature"> <div class="slds-card__body slds-card__body_inner"> <!-- Start bear list --> <template if:true={bears.data}> <lightning-input type="search" onchange={handleSearchTermChange} variant="label-hidden" class="slds-var-m-bottom_small" label="Search" placeholder="Search for bears" value={searchTerm}> </lightning-input> <lightning-layout multiple-rows="true" pull-to-boundary="small"> <template for:each={bears.data} for:item="bear"> <lightning-layout-item key={bear.Id} size="3" class="slds-var-p-around_x-small"> <c-bear-tile bear={bear}></c-bear-tile> </lightning-layout-item> </template> </lightning-layout> <!-- No bears found --> <template if:false={hasResults}> <div class="slds-align_absolute-center slds-var-m-vertical_small"> This is beary disturbing, we did not find results... </div> </template> </template> <!-- End bear list --> <!-- Data failed to load --> <template if:true={bears.error}> <div class="slds-text-color_error"> An error occurred while loading the bear list </div> </template> </div> </lightning-card> </template>
Esto hace referencia a nuestro componente Bear Tile (Mosaico de oso) con el atributobear
que definimos en los pasos anteriores. Tenga en cuenta que los archivos y la carpeta de nuestro componente se llamanbearTile
, pero la etiqueta que agregamos esc-bear-tile
. Lac
inicial representa el espacio de nombres predeterminado, anexado con el nombre del componente en letra minúscula, con rayas que separan lo que antes eran letras mayúsculas. - Implemente el código actualizado en la organización y pruebe el nuevo componente de lista. Se ve mejor con un degradado sutil.
Interactuar con el componente Bear List (Lista de osos)
Los guardaparques solicitan poder ver rápidamente el registro de un oso y modificarlo sin tener que salir de la página de inicio. Hagamos que se pueda hacer clic en los mosaicos de osos y abrir un formulario de registro Bear (Oso) editable.
- Modifique
bearTile.html
y agregue el siguiente código después de la etiqueta<lightning-card title={bear.Name} class="bear-tile">
.<div slot="actions"> <lightning-button-icon icon-name="utility:search" icon-class="bear-tile-button" variant="bare" alternative-text="Open record" onclick={handleOpenRecordClick}> </lightning-button-icon> </div>
Agregamos un botón de edición que activa la funciónhandleOpenRecordClick
. El botón se ubica en la tarjeta Lightning mediante el uso de la ranuraactions
(acciones). Una ranura es un marcador de posición para marcar que un componente superior pasa al cuerpo de un componente. - Modifique
bearTile.js
y agregue la siguiente función antes del último corchete de cierre.handleOpenRecordClick() { const selectEvent = new CustomEvent('bearview', { detail: this.bear.Id }); this.dispatchEvent(selectEvent); }
Aspectos destacados del código:- Se llama a la función
handleOpenRecordClick
cuando un usuario hace clic en el botón Abrir registro de un mosaico de oso. - La función crea y activa un evento
bearview
personalizado que contiene el Id. de registro Bear (Oso).
- Se llama a la función
- Modifique
bearList.html
y agregue un atributoonbearview={handleBearView}
a la etiquetac-bear-tile
. Esto permite capturar el eventobearview
que se activa por el componente de mosaico. El evento se gestiona en una funciónhandleBearView
.<c-bear-tile bear={bear} onbearview={handleBearView}></c-bear-tile>
- Sustituya el contenido de
bearList.js
por:import { NavigationMixin } from 'lightning/navigation'; import { LightningElement, wire } from 'lwc'; /** BearController.searchBears(searchTerm) Apex method */ import searchBears from '@salesforce/apex/BearController.searchBears'; export default class BearList extends NavigationMixin(LightningElement) { searchTerm = ''; @wire(searchBears, {searchTerm: '$searchTerm'}) bears; handleSearchTermChange(event) { // Debouncing this method: do not update the reactive property as // long as this function is being called within a delay of 300 ms. // This is to avoid a very large number of Apex method calls. window.clearTimeout(this.delayTimeout); const searchTerm = event.target.value; // eslint-disable-next-line @lwc/lwc/no-async-operation this.delayTimeout = setTimeout(() => { this.searchTerm = searchTerm; }, 300); } get hasResults() { return (this.bears.data.length > 0); } handleBearView(event) { // Get bear record id from bearview event const bearId = event.detail; // Navigate to bear record page this[NavigationMixin.Navigate]({ type: 'standard__recordPage', attributes: { recordId: bearId, objectApiName: 'Bear__c', actionName: 'view', }, }); } }
Aspectos destacados del código:- Importamos un mixin de navegación que agrupa funciones utilitarias relacionadas con la navegación. Un mixin nos permite agregar funcionalidad a una clase sin extenderla. Esto es útil cuando una clase ya extiende una superior (una clase puede extender solamente una única clase superior).
- Nuestra clase extiende el mixin de navegación aplicado a la clase base
LightningElement
. - Gestionamos el evento
bearview
en la funciónhandleBearView
. Extraemos el Id. de registro Bear (Oso) de los detalles del evento y usamos el mixin de navegación para desplazarnos a una página de registro Bear (Oso).
- Implemente el código actualizado en la organización y pruebe si puede navegar a un registro Bear (Oso) con el ícono de botón en un mosaico.
Así finaliza este paso. Refactorizamos nuestro componente en dos componentes más pequeños: Bear List (Lista de osos) y Bear Tile (Mosaico de oso). Exploramos cómo establecer una comunicación entre el componente de lista superior y el componente de mosaico secundario con un decorador @api
. También entre un componente secundario y uno superior con un evento personalizado.
En el siguiente paso, veremos cómo interactuar con otros componentes en una página Lightning.