コンポーネント間のデータバインド
この概念はやや複雑ですが、わかりやすく例を使用して説明します。parentAttr 属性のある c:parent コンポーネントがあるとします。c:parent には、parentAttr 属性の値に初期設定された childAttr のある c:child コンポーネントが含まれます。parentAttr 属性値を c:parent から c:child コンポーネントに渡します。これは、2 つのコンポーネント間のデータバインド (値バインドとも呼ばれる) になります。
{!v.parentAttr} はバインド式です。c:child の childAttr 属性値を変更すると、c:parent の parentAttr 属性が影響を受けます。その逆も同様です。
では、次のマークアップを変更してみましょう。
変更後
{#v.parentAttr} は非バインド式です。c:child の childAttr 属性値を変更しても、c:parent の parentAttr 属性は影響を受けません。その逆も同様です。
式の構文形式間の違いについて概要を次に示します。
- {#expression} (非バインド式)
- データの更新は、JavaScript で期待どおりに動作します。String などのプリミティブが値によって渡され、親と子の式でのデータ更新は分離しています。
- Array や Map などのオブジェクトは参照として渡されるため、子のデータへの変更は親に伝搬されます。ただし、親の変更ハンドラには通知されません。子に伝搬される親の変更も同様に動作します。
- {!expression} (バインド式)
- どちらのコンポーネントでのデータの更新も、双方向データバインドによって両方のコンポーネントに反映されます。同様に、変更ハンドラは親と子両方のコンポーネントでトリガされます。
非バインド式
別のコンポーネント c:childExpr を含む c:parentExpr コンポーネントのもう 1 つの例を見てみましょう。
c:childExpr のマークアップは次のようになります。
c:parentExpr のマークアップは次のようになります。
c:parentExpr コンポーネントは、非バウンド式を使用して c:childExpr コンポーネントの属性を設定します。
childExpr をインスタンス化するときに、childAttr 属性を c:parentExpr の parentAttr 属性の値に設定します。{#v.parentAttr} 構文が使用されているため、v.parentAttr 式は childAttr 属性の値にバインドされません。
c:exprApp アプリケーションは c:parentExpr を囲むラッパーです。
開発者コンソールで、c:exprApp のサイドバーにある [Preview (プレビュー)] をクリックして、ブラウザにアプリケーションを表示します。
parentAttr と childAttr の両方が「親属性」に設定されます。これは parentAttr のデフォルト値です。
次に、c:childExpr のクライアント側コントローラを作成して、コンポーネントを動的に更新できるようにします。childExprController.js のソースは次のようになります。
[Update childAttr (childAttr を更新)] ボタンを押します。この結果、childAttr が「更新された子属性」に更新されます。非バインド式を使用したため、parentAttr の値は変わりません。
では、c:parentExpr のクライアント側コントローラを追加してみましょう。parentExprController.js のソースは次のようになります。
開発者コンソールで、c:exprApp の [Update Preview (プレビューを更新)] をクリックします。
[Update parentAttr (parentAttr を更新)] ボタンを押します。今回は、parentAttr が「更新された親属性」に設定されますが、非バインド式のため childAttr は変わりません。
バインド式
次に、代わりにバインド式を使うようにコードを更新してみましょう。c:parentExpr の次の行を変更します。
変更後
開発者コンソールで、c:exprApp の [Update Preview (プレビューを更新)] をクリックします。
[Update childAttr (childAttr を更新)] ボタンを押します。この結果、childExpr のクライアント側コントローラの v.childAttr しか設定しなくても、childAttr と parentAttr の両方が「更新された子属性」に更新されます。バインド式を使用して childAttr 属性を設定したため、両方の属性が更新されました。
変更ハンドラおよびデータバインド
コンポーネントのいずれかの属性の値が変更されたとき���、変更ハンドラを自動的に呼び出す (クライアント側コントローラのアクション) ようにコンポーネントを設定できます。
バインド式を使用する場合、親または子コンポーネントの属性を変更すると、両方のコンポーネントの変更ハンドラがトリガされます。非バインド式を使用する場合は、変更がコンポーネント間で伝播されないため、変更された属性を含むコンポーネントのみで変更ハンドラがトリガされます。
では、前述の例に変更ハンドラを追加して、バインド式と非バインド式によってどのような影響を受けるか見てみましょう。
以下は、c:childExpr の更新されたマークアップです。
<aura:handler> タグに、変更ハンドラを表す name="change" が設定されています。value="{!v.childAttr}" は、変更ハンドラに childAttr 属性を追跡するよう指示します。childAttr が変更されると、onChildAttrChange というクライアント側コントローラのアクションが呼び出されます。
以下は、c:childExpr のクライアント側コントローラです。
以下は、変更ハンドラが設定された c:parentExpr の更新されたマークアップです。
以下は、c:parentExpr のクライアント側コントローラです。
開発者コンソールで、c:exprApp の [Update Preview (プレビューを更新)] をクリックします。
ブラウザのコンソールを開きます (Chrome の )。
[Update parentAttr (parentAttr を更新)] ボタンを押します。バインド式を使用しているため、c:parentExpr と c:childExpr の両方の変更ハンドラがトリガされます。
代わりに非バインド式を使用するように c:parentExpr を変更します。
開発者コンソールで、c:exprApp の [Update Preview (プレビューを更新)] をクリックします。
[Update childAttr (childAttr を更新)] ボタンを押します。この場合は、非バインド式を使用しているため、c:childExpr の変更ハンドラのみがトリガされます。