veja o exemplo https://developer.salesforce.com/docs/component-library/tools/playground/q8rtcVIBf/79/edit
Componente pai
<template> Value in Parent : {objMap.key} Value in Parent : {dummyStr} <lightning-button onclick={updateValue} label="Update Data"></lightning-button> <c-child obj-map={objMap} dummy-str={dummyStr}></c-child> </template> export default class App extends LightningElement { @track objMap = {key:"value"}; @track dummyStr updateValue() { this.objMap.key = "Value2"; this.dummyStr = Math.random(); // <---- ADD NEW VALUE this.template.querySelector("c-child").run(); } }
Componente filho
export default class Child extends LightningElement { @api objMap @api dummyStr @api run() { console.log(this.dummyStr); // <---- OLD VALUE???? } }
Como chamar o método filho do pai quando precisa usar valores @api?
Resposta
Este é o comportamento esperado. Os valores das propriedades serão passados para o filho após a conclusão da execução do método javascript, para que ele colete todas as propriedades alteradas e empurre os valores alterados para baixo na cadeia. Você pode entender isso tendo os logs no manipulador de alterações de dummyStr
conforme mostrado aqui
Você pode implementá-lo de 3 maneiras diferentes:
Opção 1: Use setTimeout (preferencial)
Conforme mostrado aqui , você pode usar setTimeout para chamar o método filho APÓS o método pai concluir o processamento. Usar setTimeout empurrará a invocação para o encadeamento assíncrono, por causa do qual ele será executado posteriormente após o encadeamento síncrono.
setTimeout(()=>this.template.querySelector("c-child").run());
Opção 2: use o manipulador de alterações
Conforme mostrado aqui , você pode usar o manipulador de alterações no filho api propriedade que será invocada após a propriedade ser alterada.
@api get dummyStr() { return this._dummyStr; } set dummyStr(value) { this._dummyStr = value; console.log("dummyStr changed => ", this._dummyStr, value); this.run(); }
Opção 3: use o parâmetro do método
Conforme mostrado aqui , passe as propriedades alteradas necessárias como parâmetros do método.
this.template.querySelector("c-child").run(this.dummyStr);
Comentários
- Muito obrigado! Eu não ' não sabia sobre a primeira opção. Pensei que os valores entre os componentes enviam por link.
Resposta
Tente isto:
import { LightningElement, track } from "lwc"; export default class App extends LightningElement { @track objMap = {key:"value"}; @track dummyStr updateValue() { this.objMap.key = "Value2"; this.dummyStr = Math.random(); this.template.querySelector("c-child").run(this.dummyStr); } }
CRIANÇA:
import { LightningElement, track, api } from "lwc"; export default class Child extends LightningElement { @api objMap @api dummyStr @api run(dummyStr) { console.log(dummyStr); } }
Depois de clicar em “Atualizar dados”:
SAÍDA:
Comentários
- Eu apenas pensei que os valores entre os componentes enviam por link. Não estou esperando esse comportamento