Web 组件:如何从父组件访问子组件实例
Web Components: how to access child component instances from a parent
编辑 我在这个问题中遗漏了一些细节,但假设这两个元素都已经定义。此外,在现实世界的问题中,DOM 树更大,子组件 插入 到父组件中。找到子组件没有问题。
我有两个网络组件:Parent
和 Child
。
我可能会像这样在标记中使用这些组件:
<parent-element>
<child-element></child-element>
</parent-element>
Child
组件具有我想向父级公开的逻辑。
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 returns 一个 HTMLElement
而不是 Web 组件 instance.
有没有办法以类似的方式获取组件的实例?我希望能够遍历 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>
编辑 我在这个问题中遗漏了一些细节,但假设这两个元素都已经定义。此外,在现实世界的问题中,DOM 树更大,子组件 插入 到父组件中。找到子组件没有问题。
我有两个网络组件:Parent
和 Child
。
我可能会像这样在标记中使用这些组件:
<parent-element>
<child-element></child-element>
</parent-element>
Child
组件具有我想向父级公开的逻辑。
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 returns 一个 HTMLElement
而不是 Web 组件 instance.
有没有办法以类似的方式获取组件的实例?我希望能够遍历 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>