簡體   English   中英

Aurelia有條件地包裝組件中的插槽

[英]Aurelia conditionally wrapping slots in components

我正在創建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>

開箱即用,沒有直接的方法像$slots屬性那樣做,但是你應該能夠通過模板控制器實例本身訪問插槽: au.controller.view.slots - 內部的特定插槽這個數組有關於插槽本身及其子節點的更多信息。

以下是具有模態組件(自定義模態元素)的Aurelia應用程序的示例。 模態本身有一個插槽,可以在其中投影HTML。 我們有一個標題,正文和頁腳。

我們的自定義元素內的每個預定義插槽都應顯示在children對象內部,其中屬性名稱是插槽的名稱。 如果您沒有為插槽(默認插槽)提供名稱,則其內部名稱為: __au-default-slot-key__

我們首先檢查插槽是否存在然后檢查其子節點的長度,每個插槽中都存在children數組。 如果插槽中沒有投射HTML,則子節點長度為零。 這是可靠的,因為在插槽內定義的默認內容不會被放入children數組中,只有投影的HTML才會。

您將看到工作主要在modal.htmlmodal.html ,但要密切關注modal.js ,我們在其中注入自定義元素的元素引用,然后使用au訪問Aurelia實例以獲取包含我們的插槽的控制器本身。

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

使用CSS:空選擇器

CSS是這項工作的正確工具,而不是Aurelia。 :空選擇器將允許您在未填充插槽時display: none div.actions

.card .actions:empty {
  display: none;
}

根據CSS-Tricks解釋:空選擇器規范 ,空格導致空無法匹配,因此我們只需要移除插槽周圍的空白區域。

<div class="actions"><slot name="actions"></slot></div>

這里的工作示例: https//gist.run/?id = 040775f06aba5e955afd362ee60863aa

這是我用來檢測是否有任何插槽有子節點的方法(不包括HTML注釋)

打字稿

import { autoinject } from 'aurelia-framework';

@autoinject
export class MyClass {
    private constructor(readonly element: Element) {
    }

    private attached() {
    }

    get hasSlotChildren(): boolean {
        if (!this.element ||
            !(this.element as any).au) {
            return false;
        }
        let childrenCount = 0;
        const slots = (this.element as any).au.controller.view.slots;
        for (let slotName of Object.keys(slots)) {
            const slot = slots[slotName];
            if (slot.children && 
                slot.children.length > 0) {
                for (let child of slot.children) {
                    if (child instanceof Comment) {
                        // Ignore HTML comments
                        continue;
                    }
                    childrenCount++;
                }
            }
        }
        return childrenCount > 0
    }
}

HTML

<template 
    class="my-class" 
    show.bind="hasSlotChildren"
>
    <slot></slot>
</template>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM