Как определить количество детей в слоте
Есть ли способ узнать, сколько детей содержится в названном слоте? В моем компоненте Stencil есть что-то вроде этого в моей функции рендеринга:
<div class="content">
<slot name="content"></slot>
</div>
Я хочу по-разному стилизовать div.content в зависимости от того, сколько детей в слоте. Если в слоте нет дочерних элементов, то div.content style.display='none', в противном случае к div.content применяется несколько стилей, которые позволяют правильно отображать дочерние элементы на экране.
Я пытался сделать:
const divEl = root.querySelector( 'div.content' );
if( divEl instanceof HTMLElement ) {
const slotEl = divEl.firstElementChild;
const hasChildren = slotEl && slotEl.childElementCount > 0;
if( !hasChildren ) {
divEl.style.display = 'none';
}
}
однако это всегда сообщает hasChildren = false, даже если в слот вставлены предметы.
2 ответа
Если вы запрашиваете хост-элемент, вы получите весь выделенный контент внутри него. Это означает, что потомками хост-элемента будет весь контент, который будет вставлен в слот. Например, попробуйте использовать следующий код, чтобы увидеть его в действии:
import {Component, Element, State} from '@stencil/core';
@Component({
tag: 'my-component',
styleUrl: 'my-component.css',
shadow: true
})
export class MyComponent {
@Element() host: HTMLElement;
@State() childrenData: any = {};
componentDidLoad() {
let slotted = this.host.children;
this.childrenData = { hasChildren: slotted && slotted.length > 0, numberOfChildren: slotted && slotted.length };
}
render() {
return (
<div class="content">
<slot name="content"></slot>
<div>
Slot has children: {this.childrenData.hasChildren ? 'true' : 'false'}
</div>
<div>
Number of children: {this.childrenData.numberOfChildren}
</div>
</div>);
}
}
Принятое решение на самом деле не является правильным способом сделать это. Даже пример кода неверен. Он использует именованный слотname="content"
. Только элементы сslot="content"
атрибут из светлого DOM будет помещен в этот слот; следовательно, просто проверкаthis.host.children
совсем не достаточно.
Вместо этого вам следует работать с событием slotchange (преимущество которого также заключается в правильном отражении динамических изменений):