こんにちは、アンダーソンです。
今回はコンポーネントをネストさせて、イベントを呼び出して〜
といった動作の実装をしていきます。
イメージをつかむ
前回作成したコンポーネントを分割して、それをネストさせてみます。
前回作成したのがこちらです。
<template>
<lightning-input onchange={changeWord} type="search" class="slds-m-bottom_small" value={searchWord}></lightning-input>
<lightning-button onclick={search} label="検索" class="slds-m-left_x-small"></lightning-button>
<template if:true={hasChanged}>
<lightning-layout multiple-rows="true" pull-to-boundary="small">
<template for:each={tests} for:item="test">
<lightning-layout key={test.Id} size="3" class="slds-p-around_x-small">
<lightning-card title={test.Name}>
<div class="slds-p-horizontal_small">
<div class="slds-media">
<div class="slds-media__body">
<p class="slds-m-bottom_xx-small">{test.Text__c}</p>
<p class="slds-m-bottom_xx-small">{test.CheckBox__c}</p>
<p class="slds-m-bottom_xx-small">{test.Datetime__c}</p>
<p class="slds-m-bottom_xx-small">{test.PickList__c}</p>
</div>
</div>
</div>
</lightning-card>
</lightning-layout>
</template>
</lightning-layout>
</template>
</template>
このコンポーネントは入力された値を受けてApexを呼び出し、
返却されたリストを
template for:each={tests} for:item=”test”
内で繰り返し表示させるものでした。
これを入力部分とリスト部分に分けてみたいと思います。
イメージは下記のような感じです。

myComponent 親
|__ inputComponent 子
|__ listComponent 子
という形です。
ではやっていきましょう。
コンポーネントを分割しよう
上記のマークアップの場合、分けたいのは
2.3行目の入力検索の部分と、4-23行目の結果表示箇所です。
この部分をそれぞれのhtmlに切り離します。
そしてそれぞれをmyComponent側からマークアップして表示させます。
<template>
<c-input-component></c-input-component>
<c-list-component></c-list-component>
</template>
これでOKです。まだ完全ではありませんが、一旦表示だけはできました。

ただこのままだともちろん、値は取れないので検索結果も表示されません。
なので裏側の動作であるJavaScriptを書いていきます。
イベントを作成しよう
まず今回のトリガになるのが、文字を入力して、検索ボタンを押した際です。
このボタンが押されたら、子から親に対してイベントを起こし、
子で入力された検索ワードを親に渡して処理をしていきます。
ではまず親側から子のイベントを呼び出せるようにしてあげます。
<c-input-component onsearch={handlerSearch}></c-input-component>
onsearch属性はinputComponent.jsで使う予定の関数です。
handlerSearchは親であるmyComponentで後ほど作っていきます。
次にinputComponent.jsでボタンが押された際の挙動を書いていきます。
search(){
const event = new CustomEvent('search', {
detail: this.searchWord
});
this.dispatchEvent(event);
}
CustomEventオブジェクトを作成し、detailとして検索文字列を渡します。
その後dispatchEventで作成したCustomEventを起動させます。
イベントを受け取って処理しよう
次にそれを受け取るmyComponent.jsの動きをみていきます。
export default class MyComponent extends LightningElement {
tests;
searchWord;
hasChanged;
handleSearch(evt){
this.searchWord = evt.detail;
serachRecord({serachWord: this.searchWord})
.then (result => {
this.tests = result;
this.hasChanged = (this.tests.length > 0);
})
}
}
handleSearch(evt)で先ほどのイベントを受け取り、検索文字にdetailを代入しています。
その後前回でもやったApexの呼び出しを行い、リストにデータを格納しています。
さらに検索結果がTrueの場合のみ結果を表示させるのでhasChangedに真偽値を代入しています。
受け取る側のlistComponentをみてみましょう。
import { LightningElement, api } from 'lwc';
export default class ListComponent extends LightningElement {
@api tests;
@api hasChanged;
}
@apiアノテーションで配列と表示非表示用のBooleanを公開しています。
さらにmyComponent.htmlでこの公開された変数に対して、代入します。
<c-list-component tests={tests} has-changed={hasChanged}></c-list-component>
これでOKです。

まとめ
挙動自体は以前と変わりませんが、コンポーネントを分割してイベントの呼び出し、値をコンポーネントに渡すという事ができました。
今回は簡単なネストですが、実際にはもっと複雑に絡み合ってくると思います。
しっかり勉強していかないといけないですね。
今回のコードも全てみたい方はぜひGitHubに公開していますので
ご覧ください。
コメント