2017-07-15 13 views
1

私は今、material-components-webをラップするAureliaコンポーネントを作成しています。複数のコンテンツセクション(アクションなど)を実装する正しい方法が何であるか疑問に思っています。コンポーネント内の条件付きラッピングスロットAurelia

スロットは正しい選択肢だと思われますが、実際にアクションが存在する場合にのみ、常にテンプレートにアクションdivを置くことはできません。

簡単に言えば、スロットがコンポーネントテンプレート内で定義されているかどうかを確認する必要があります。

<template> 
    <div class="card"> 
     <div class="content"> 
      <slot></slot> 
     </div> 

     <!-- somehow check here if the slot has been defined --> 
     <div class="actions"> 
      <slot name="actions"></slot> 
     </div> 
    </div> 
</template> 

答えて

2

はすぐに、しかし、あなたは、テンプレートコントローラインスタンス自体を経由してスロットにアクセスできるようになり、$slotsプロパティのようにこれを行うには直接的な方法はありません:au.controller.view.slots - の内の特定のスロットこの配列には、スロット自体とその子要素に関する詳細情報があります。

Hereは、モーダルコンポーネント(カスタムモーダル要素)を持つAureliaアプリケーションの例です。モーダル自体には、内部にHTMLを投影できるスロットがあります。ヘッダー、本文、フッターがあります。

カスタム要素内の各定義済みのスロットは、childrenオブジェクトの内側に表示されます。プロパティ名は、スロットの名前です。スロット(デフォルトスロット)の名前を指定しない場合は、内部での名前は__au-default-slot-key__です。

まず、スロットが存在するかどうかを確認し、子の長さを確認したら、各スロット内にchildrenアレイが存在するかどうかを確認します。スロットにHTMLが投影されていない場合は、子の長さがゼロになります。これは、スロット内で定義されたデフォルトのコンテンツが配列childrenに入れられないため、信頼できるものです。投影されるのはHTMLだけです。

あなたは仕事がほとんどmodal.htmlの内部で行われている参照が、我々はカスタム要素の要素の参照を注入して、私たちのスロットを含むコントローラを取得するauを使用してオーレリアインスタンスにアクセスmodal.jsに細心の注意を払うだろう自体。

このアプローチには1つの注意点があります。if.bindを使用して、カスタム要素内のHTMLを条件付きで削除することはできません。スロットを含むDIVでif.bindを使用すると、実際にスロット参照が削除されるため、スロット参照が削除されます。この問題を回避するには、show.bindを使用してください(私の提供する実行例のように)。

+0

完璧に、本当に機能します。私はこのトピックで何も見つけることができなかったことに驚いています。誰もがカスタム属性を使用してクラスと一緒にdivを装飾しているように見えます。 – marekpw

+0

質問に続き、多分無関係です:[this](https://gist.run/?id=3e6875bac99fb2fb984039b88a873049)が動作しない理由を知っていますか?私はいくつかのロジックをビューモデルに抽象化しようとしました。なぜなら、私は多くの場所で定義されたスロットをチェックするためです。添付された()が起こる前に、slotDefined()メソッドが一度だけ呼び出されたようです。また、@computedFrom( '$ slots')デコレータを使用してみましたが、コンポーネントがレンダリングされず(エラーなし)、定義されたスロットだけがレンダリングされます。 – marekpw

+0

[こちらのハック](https://gist.run/?id=abf47aa5d72feaeedcd7bced74f2f6f4)でどうぞ。 .bindは関数を呼び出すことができないので、ゲッターを使用して回避する必要がありました。すべてが完璧に機能します。もう一度あなたの助けに感謝します。 – marekpw

関連する問題