Criar um componente filho e interagir com ele
Nossa base de código cresceu nas últimas etapas. Vamos tirar um instante para refatorar nosso componente de lista de ursos em vários componentes menores. Vamos mover o código dos blocos de ursos para um novo componente.
Criar o componente de bloco de urso
- No VS Code, clique com o botão direito do mouse na pasta
lwc
e clique em SFDX: Create Lightning Web Component (Criar componente Web do Lightning). - Dê ao componente o nome
bearTile
. - Abra
bearList.html
e corte todo o código entre<!-- Start bear tile -->
e<!-- End bear tile -->
. - Cole o código dentro das marcas
template
debearTile.html
. Quando terminar,bearTile.html
deve ficar assim.<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>
- Substitua o conteúdo 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`, }; }
Adicionamos uma propriedadebear
decorada com@api
. Isso expõe a propriedadebear
a qualquer componente pai. - Exclua
bearList.css
. - Crie outro arquivo
bearTile.css
no diretóriobearTile
e cole o seguinte código no arquivo.: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
e substitua o conteúdo entre os comentários<!-- Start bear tile -->
e<!-- End bear tile -->
por<c-bear-tile bear={bear}></c-bear-tile>
. Quando terminar,bearList.html
deve ficar assim.<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>
Isso referencia nosso componente de bloco de urso com o atributobear
que definimos nas etapas anteriores. Observe que a pasta e os arquivos do nosso componente se chamambearTile
, mas a marca que adicionamos éc-bear-tile
. Oc
do início representa o namespace padrão, acrescido do nome do componente em minúsculas, com traços separando o que costumavam ser maiúsculas. - Implante o código atualizado na organização e teste seu novo componente de lista. Ele deve ficar melhor com um leve gradiente.
Interagir com o componente de lista de ursos
Os guardas estão pedindo para ter a capacidade de olhar rapidamente o registro de um urso e editá-lo sem ter que sair da página inicial. Vamos tornar os blocos de ursos clicáveis para abrir um formulário de registro de urso editável.
- Edite
bearTile.html
e adicione o código a seguir após a marca<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>
Adicionamos um botão de edição que aciona a funçãohandleOpenRecordClick
. O botão é colocado no cartão do Lightning com o uso do slotactions
. Um slot é um espaço reservado para marcação que um componente pai transmite ao corpo de um componente. - Edite
bearTile.js
e adicione a função a seguir antes do último colchete de fechamento.handleOpenRecordClick() { const selectEvent = new CustomEvent('bearview', { detail: this.bear.Id }); this.dispatchEvent(selectEvent); }
Destaques do código:- A função
handleOpenRecordClick
é chamada quando um usuário clica no botão para abrir o registro de um bloco de urso. - A função cria e aciona um evento
bearview
personalizado que contém a ID de registro do urso.
- A função
- Edite
bearList.html
e adicione um atributoonbearview={handleBearView}
à marcac-bear-tile
. Isso nos permite capturar o eventobearview
que é acionado pelo componente de bloco. O evento é processado em uma funçãohandleBearView
.<c-bear-tile bear={bear} onbearview={handleBearView}></c-bear-tile>
- Substitua o conteúdo 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', }, }); } }
Destaques do código:- Importamos um mixin de navegação que reúne funções de utilitários que lidam com navegação. Um mixin permite adicionar funcionalidades a uma classe sem estendê-la. Isso é útil quando uma classe já estende uma classe pai (uma classe só pode estender um único pai).
- Nossa classe estende o mixin de navegação aplicado à classe base
LightningElement
. - Processamos o evento
bearview
na funçãohandleBearView
. Extraímos a ID de registro de urso dos detalhes do evento e usamos o mixin de navegação para navegar até uma página de registro de urso.
- Implante o código atualizado na organização e teste se você consegue navegar até um registro de urso com o ícone de botão em um bloco.
É tudo para esta etapa. Refatoramos nosso componente em dois componentes menores: a lista de ursos e um bloco de urso. Exploramos como comunicar do componente de lista pai para o componente de bloco filho com um decorador @api
. Também vimos como comunicar de um filho com um pai usando um evento personalizado.
Na próxima etapa, veremos como interagir com outros componentes em uma página do Lightning.