javascript - Web 组件 : how to access child component instances from a parent

标签 javascript web-component native-web-component

编辑 我在这个问题中遗漏了一些细节,但假设这两个元素都已定义。此外,在现实世界的问题中,DOM 树更大,子组件被插入到父组件中。找到子组件没有问题。

我有两个 Web 组件:ParentChild

我可能会像这样在标记中使用这些组件:

<parent-element>
  <child-element></child-element>
</parent-element>

组件具有我想向父级公开的逻辑。

class Child extends HTMLElement {
  constructor() {
    ...
  }

  publicMethod() {
    console.log('call me from the parent component');
  }
}

理想情况下,我想像这样从父级调用子方法:

class Parent extends HTMLElement {
  constructor() {
    ...
  }

  someTrigger() {
    const child = this.shadowRoot.querySelector('child-element');
    child.publicMethod();
  }
}

但是这不起作用,因为 child 是一个 HTMLElement,因为 querySelector() API 返回一个 HTMLElement 而不是网络组件实例

有没有办法以类似的方式获取组件的实例?我希望能够遍历 Parent 组件影子树以找到特定的组件实例。

最佳答案

小心 whenDefined ;
它告诉您 Web 组件是定义的,而不是在 DOM 中解析时:

只要您保留 <child-element>lightDOM 中,<slot>和 shadowDOM 与它们无关。

.as-console-wrapper {max-height:100%!important;top:0;zoom:.88}
.as-console-row:nth-child(n-6) {background:#0057B7!important;color:#FFD500!important}
.as-console-row:nth-child(n+6) {background:#FFD500!important;color:#0057B7!important}
.as-console-row-code{padding:0!important}
<script>
  console.clear();
  class Component extends HTMLElement {
    constructor() {
      super();
      console.log(this.nodeName, "constructor")
    }
    connectedCallback(){
      console.log("connectedCallback", this.nodeName, this.children.length, "children");      
    }
  }
  customElements.define("child-component", class extends Component {
    foo() {
      console.log("Executed <child-element>.foo()");
    }
  });
  customElements.define("parent-component", class extends Component {
    connectedCallback() {
      super.connectedCallback();
      customElements.whenDefined('child-component')
                    .then(() => console.log("Promise resolved, <child-component> IS defined!"));
      setTimeout(() => { // wait till lightDOM is parsed
        console.log("After setTimeout",this.nodeName,"has", this.children.length, "children");
        this.querySelectorAll("child-component").forEach(child => child.foo());
      })
    }
  })
</script>
<parent-component>
  <child-component></child-component>
  <child-component></child-component>
</parent-component>

关于javascript - Web 组件 : how to access child component instances from a parent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71358910/

相关文章:

javascript - 根据另一个不工作的元素过滤选择元素

javascript - 使用 jQuery 添加/删除类

javascript - 我可以更改 key 对数据的存储方式以使访问非常高效吗?

javascript - 在 Shadow DOM 中创建单选按钮

javascript - 如何将 JavaScript 添加到自定义元素?

javascript - Magento 尝试触发鼠标悬停效果

javascript - polymer : Watch the changed Property from outside of an Component

javascript - 在 ES5 中创建自定义元素 v1,而不是 ES6

javascript - LitElement 不会为原生 Web 组件设置 textContent