LitElement - 模板中的 ForEach children

LitElement - ForEach children in template

我想为每个 child 创建 <slot>,例如这里我有一个菜单,我希望每个 child 都放在 <div>item class.
我创建了一个小实用函数来映射 children:

export function ChildrenMap(el: LitElement, map: (el: HTMLElement, index: number) => TemplateResult): TemplateResult[] {
    console.log(el.children.length) // Returns 0 in Google Chrome and I guess Edge too.
    return (Array.prototype.slice.call(el.children) as HTMLElement[])
                .map(map);
}

然后我在渲染函数中使用它:

render() {
    return html`
        <nav>
        ${ChildrenMap(this, (ele, index) => {
            let id = ele.id ? ele.id :  `item-${index}`;
            ele.setAttribute('slot', id);

            let klass = 'item';
            if(this.selected && this.selected == index) {
                klass += " selected";
            }

            return html`
                <div class="${klass}" data-index="${index}">
                <slot name="${id}"></slot>
                </div>`;
        })}
        </nav>
    `;
}

这在 FireFox 中工作正常,但正如我上面的评论所说,在 Google Chrome 中,元素在渲染点有 0 children,所以 <nav> 为空。
谁能解释为什么元素在渲染点有 0 children? 也许我的做法不对,有人有其他选择吗?

非常感谢

更新:Mozilla/FireFox 2021 年初修复了此错误

实际上 FireFox 在这一点上是错误的,它调用 connectedCallback 太迟了

Mozilla 工程师 Anne van Kesteren 确认的错误:

有关详细信息,请参阅 Whosebug 线程:

connectedCallback中还没有DOMchildren阅读因为所有DOMchildren仍在解析中。 (它可能是一个非常大的 DOM 结构)

work-around(如你所见)是等待:

connectedCallback(){
  setTimeout(()=>{
    // now you can access this. DOM children
  },0);
}

所有带有 Promises 等的建议有效地做同样的事情:等到事件循环为空