2017-07-15 48 views
1

我正在創建包含material-components-web,cards specifically的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,但密切關注modal.js我們注入的自定義元素的元素的引用,然後使用au獲得包含我們的槽控制器訪問奧裏利亞實例本身。

這種方法有一個警告:您不能使用if.bind有條件地刪除您的自定義元素內的HTML。如果在包含插槽的DIV上使用if.bind,則實際上會刪除其插槽引用,因此無法檢查它。要解決這個問題,只需使用show.bind(就像我在我提供的運行示例中那樣)。

+0

完美的作品,非常酷。我很驚訝在這個主題上找不到任何東西,每個人似乎都使用自定義屬性來裝飾類,這看起來像這樣簡單的東西的矯枉過正。 – marekpw

+0

後續問題,可能無關:你知道爲什麼[this](https://gist.run/?id=3e6875bac99fb2fb984039b88a873049)不起作用嗎?我試圖將一些邏輯抽象到視圖模型,因爲我將在許多地方檢查定義的插槽。在attach()發生之前,似乎slotDefined()方法只被調用一次。我也嘗試使用@computedFrom('$ slots')裝飾器,但現在組件根本不渲染(沒有錯誤),只有定義的插槽呈現。 – marekpw

+0

現在就用[this hack](https://gist.run/?id=abf47aa5d72feaeed7bced74f2f6f4)。看來.bind無法調用函數,所以我必須使用getter來解決它。一切都很完美,再次感謝你的幫助。 – marekpw