Trabajar con listas de registros
Cómo crear el componente Bear List (Lista de osos)
Los guardaparques quieren ver el directorio de osos directamente desde la página de inicio. Se le asignó la tarea de implementar esa lista de osos.
- En VS Code, haga clic con el botón secundario en la carpeta lwcy, luego, en SFDX: Create Lightning Web Component (Crear componente web Lightning).
- Asigne el nombre bearListal componente.
- Modifique el archivo bearList.js-meta.xmly sustituya<isExposed>false</isExposed>por estas líneas.<isExposed>true</isExposed> <targets> <target>lightning__AppPage</target> <target>lightning__RecordPage</target> <target>lightning__HomePage</target> </targets> Así podrá ubicar su componente en cualquier tipo de página en el Generador de aplicación Lightning.
- Sustituya el contenido de bearList.htmlpor:<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}> <lightning-layout multiple-rows="true" pull-to-boundary="small"> <template for:each={bears} for:item="bear"> <lightning-layout-item key={bear.Id} size="3" class="slds-var-p-around_x-small"> <!-- Start bear tile --> <lightning-card title={bear.Name} class="bear-tile"> <div class="slds-var-p-horizontal_small bear-tile-body"> <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> <!-- End bear tile --> </lightning-layout-item> </template> </lightning-layout> </template> <!-- End bear list --> <!-- Data failed to load --> <template if:true={error}> <div class="slds-text-color_error"> An error occurred while loading the bear list </div> </template> </div> </lightning-card> </template>Aspectos destacados del código:- La etiqueta template(plantilla) con las directivasfor:eachyfor:itemse utiliza para iterar los registrosbears(osos). Cada elemento de iteración se transfiere a la propiedadbear.
- Cada iteración de la plantilla se marca con un atributo key(clave) especial.keydebe tener un valor único en el contexto de la iteración. Este es el Id. de cada oso en nuestro componente.
 
- La etiqueta 
- Sustituya el contenido de bearList.jspor:import { LightningElement } from 'lwc'; import ursusResources from '@salesforce/resourceUrl/ursus_park'; /** BearController.getAllBears() Apex method */ import getAllBears from '@salesforce/apex/BearController.getAllBears'; export default class BearList extends LightningElement { bears; error; appResources = { bearSilhouette: `${ursusResources}/standing-bear-silhouette.png`, }; connectedCallback() { this.loadBears(); } loadBears() { getAllBears() .then(result => { this.bears = result; }) .catch(error => { this.error = error; }); } }Aspectos destacados del código:- Importamos el adaptador ursusResources, que nos da acceso a un recurso estático asociado a nuestra aplicación. Utilizamos este adaptador para crear un objetoappResourcesque expone la dirección URL de imagen con la silueta de un oso en la plantilla.
- Importamos el adaptador getAllBears, que nos permite interactuar con el método ApexBearController.getAllBears(). La claseBearControllerse agrupa en el código que implementó al comienzo de este proyecto. El métodogetAllBearsmuestra el resultado de una consulta que recupera todos los registros Bear (Oso).
- Implementamos la función connectedCallback, que nos permite ejecutar el código después de cargar el componente. Utilizamos esta función para llamar a la funciónloadBears.
- La función loadBearsllama al adaptadorgetAllBears. El adaptador llama a nuestro código Apex y muestra una promesa de JS. Utilizamos la promesa para guardar los datos obtenidos en la propiedadbearso para reportar errores. La recuperación de datos con este método se denomina Apex imperativo.
 
- Importamos el adaptador 
- Cree un nuevo archivo bearList.cssen el directoriobearListy pegue el siguiente código en el archivo..bear-tile { display: block; border: 1px solid #d2955d; border-radius: .25rem; background-color: #fae8d2; } .bear-silhouette { height: 100px; }Estas reglas de CSS agregan bordes a nuestras tarjetas de osos y establecen la altura de la imagen con la silueta de un oso.
- Implemente el código actualizado en la organización. Haga clic con el botón secundario en la carpeta default (predeterminada) y, luego, en SFDX: Deploy Source to Org (Implementar fuente en organización).
Cómo agregar el componente Bear List (Lista de osos) a la página de inicio de la aplicación
Vamos a agregar el nuevo componente a la página de inicio de la aplicación.
- En su organización, desde el Iniciador de aplicación ( ), busque y seleccione Ursus Park. ), busque y seleccione Ursus Park.
- Haga clic en Setup (Configuración) ( ) y seleccione Edit Page (Modificar página). ) y seleccione Edit Page (Modificar página).
- En Custom Components (Componentes personalizados), busque el componente bearList y arrástrelo a la esquina superior izquierda de la página.
- Haga clic en Save (Guardar) y luego en Back (Atrás) para volver a la página de inicio y revisar su trabajo.

Utilizar Apex conectado
Ahora, vamos a explorar una nueva forma de recuperar la lista de osos. Utilizaremos Apex conectado en lugar de Apex imperativo.
- Modifique bearList.htmly reemplace<template if:true={bears}>por<template if:true={bears.data}>.
- Reemplace <template for:each={bears} for:item="bear">por<template for:each={bears.data} for:item="bear">.
- Reemplace <template if:true={error}>por<template if:true={bears.error}>. En este punto, la plantilla es casi igual a la de Apex imperativo. Ahora accedemos a la lista de osos mediante una llamada abears.dataen lugar de solo abearsy también recuperamos errores conbears.erroren lugar de solo conerror.
- Sustituya el contenido de bearList.jspor:import { LightningElement, wire } from 'lwc'; import ursusResources from '@salesforce/resourceUrl/ursus_park'; /** BearController.getAllBears() Apex method */ import getAllBears from '@salesforce/apex/BearController.getAllBears'; export default class BearList extends LightningElement { @wire(getAllBears) bears; appResources = { bearSilhouette: `${ursusResources}/standing-bear-silhouette.png`, }; }Simplificamos significativamente el código JS al decorar nuestra propiedadbearscon Apex conectado. Toda la información que necesitamos ahora proviene de esta única línea:@wire(getAllBears) bears;
- Implemente el código actualizado en la organización y observe que se comporta de la misma forma que con Apex imperativo.
Especificar parámetros en las llamadas de Apex
La cantidad de habitantes en Ursus Park está aumentando. Los guardaparques desean poder filtrar la lista de osos para buscarlos rápidamente. Agreguemos una barra de búsqueda a nuestra lista de osos para ayudarlos.
- Modifique bearList.htmly agregue el siguiente código después de la etiqueta<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>Se agregará un campo de entrada de búsqueda. Cuando el valor cambia, llamamos a la funciónhandleSearchTermChange.
- Agregue el siguiente código tras la etiqueta de cierre </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>Se agregará un mensaje que indica que no se encontraron resultados. Este mensaje solo se muestra cuando la expresiónhasResultses falsa.
- Sustituya el contenido de bearList.jspor:import { LightningElement, wire } from 'lwc'; import ursusResources from '@salesforce/resourceUrl/ursus_park'; /** BearController.searchBears(searchTerm) Apex method */ import searchBears from '@salesforce/apex/BearController.searchBears'; export default class BearList extends LightningElement { searchTerm = ''; @wire(searchBears, {searchTerm: '$searchTerm'}) bears; appResources = { bearSilhouette: `${ursusResources}/standing-bear-silhouette.png`, }; 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); } }Aspectos destacados del código:- Agregamos una propiedad reactiva searchTermy la especificamos como un parámetro de nuestra llamada de Apex conectado ensearchBears.
- La función handleSearchTermChangese utiliza para reaccionar a cambios en el valor del campo de entrada de búsqueda. Introducimos intencionalmente una demora de 300 milisegundos cuando actualizamos la propiedad reactivasearchTerm. Si una actualización está pendiente, la cancelamos y volvemos a programar una nueva en 300 ms. Esta demora reduce la cantidad de llamadas de Apex cuando el usuario está escribiendo las letras para formar una palabra. Cada nueva letra desencadena una llamada ahandleSearchTermChange, pero, idealmente, solo se llama asearchBearscuando el usuario termina de escribir. Esta técnica se denomina debouncing.
- Exponemos la expresión hasResultspara comprobar si nuestra búsqueda nos muestra osos.
 
- Agregamos una propiedad reactiva 
- Implemente el código actualizado en la organización y compruebe que la búsqueda funcione con o sin resultados.

Así finaliza este paso. Vimos cómo gestionar listas de registros con Apex imperativo y luego con Apex conectado, y aprendimos cómo especificar parámetros en nuestras llamadas de Apex. El código de nuestro componente creció de manera significativa en el proceso, así que, ahora, vamos a dividirlo en subcomponentes para que sea más fácil de mantener.
