Zobacz przykład https://developer.salesforce.com/docs/component-library/tools/playground/q8rtcVIBf/79/edit
Komponent nadrzędny
<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(); } }
Komponent podrzędny
export default class Child extends LightningElement { @api objMap @api dummyStr @api run() { console.log(this.dummyStr); // <---- OLD VALUE???? } }
Jak wywołać metodę potomną od rodzica, gdy trzeba użyć wartości @api?
Odpowiedź
Jest to oczekiwane zachowanie. Wartości właściwości zostaną przekazane podrzędnemu po zakończeniu działania metody javascript, aby zebrała wszystkie zmienione właściwości i wypchnęła zmienione wartości w dół łańcucha. Możesz to zrozumieć, mając dzienniki w module obsługi zmian dummyStr
, jak pokazano tutaj
Możesz to zaimplementować na 3 różne sposoby:
Opcja 1: użyj setTimeout (preferowana)
Jak pokazano tutaj , możesz użyć setTimeout do wywołania metody potomnej PO zakończeniu przetwarzania metody nadrzędnej. Użycie setTimeout spowoduje przeniesienie wywołania do wątku asynchronicznego, z powodu którego zostanie uruchomione później po wątku synchronicznym.
setTimeout(()=>this.template.querySelector("c-child").run());
Opcja 2: Użyj procedury obsługi zmiany
Jak pokazano tutaj , możesz użyć funkcji obsługi zmian w podrzędnym api , która zostanie wywołana po zmianie właściwości.
@api get dummyStr() { return this._dummyStr; } set dummyStr(value) { this._dummyStr = value; console.log("dummyStr changed => ", this._dummyStr, value); this.run(); }
Opcja 3: użyj parametru metody
Jak pokazano tutaj , przekaż wymagane zmienione właściwości jako parametry metody.
this.template.querySelector("c-child").run(this.dummyStr);
Komentarze
- Dziękuję bardzo! Nie ' nie wiedziałem o pierwszej opcji. Wydawało mi się, że wartości między komponentami są przesyłane przez łącze.
Odpowiedź
Spróbuj tego:
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); } }
DZIECKO:
import { LightningElement, track, api } from "lwc"; export default class Child extends LightningElement { @api objMap @api dummyStr @api run(dummyStr) { console.log(dummyStr); } }
Po kliknięciu „Aktualizuj dane”:
WYJŚCIE:
Komentarze
- Właśnie Pomyślałem, że wartości między komponentami przesyłane są przez łącze. Nie spodziewam się takiego zachowania