Developer

【Lightning Web Component】コンポーネントをネストさせてみよう【Salesforce】

Developer
この記事は約7分で読めます。

こんにちは、アンダーソンです。
今回はコンポーネントをネストさせて、イベントを呼び出して〜
といった動作の実装をしていきます。

スポンサーリンク

イメージをつかむ

前回作成したコンポーネントを分割して、それをネストさせてみます。
前回作成したのがこちらです。

<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に公開していますので
ご覧ください。

その他の開発に関する記事はこちらです。

Developerも含めた試験問題にチャレンジしてみましょう。

コメント