我正在为我的Web组件实现Orchestrator模式,如下所示:
$ echo 800001.1.pull | awk -F'.pull' '{ new=sprintf("%14s%s",$1,FS); gsub(/ /,0,new); print $0, new }'
800001.1.pull 000000800001.1.pull
$ echo 800001.12.345.pull | awk -F'.pull' '{ new=sprintf("%14s%s",$1,FS); gsub(/ /,0,new); print $0, new }'
800001.12.345.pull 0800001.12.345.pull
我创建的所有自定义元素都使用<body>
<my-controller>
<div>
<my-list>
<span>
<my-item></my-item>
</span>
</my-list>
</div>
</my-controller>
</body>
使用Shadow DOM。
我想从内部Web组件访问const root = super.attachShadow({mode: "open"}); root.appendChild(...);
中的my-controller
组件:
connectedCallback()
奇怪的是:我只能访问直接父级Web控件。
因此,如果在public connectedCallback(): void
{
if (this.isConnected)
{
for (let node = this.parentElement; node; node = node.parentElement)
if (node instanceof ContainerBase)
{
this._service = (<ContainerBase>node).GetService(this);
break;
}
if (this._service) this.Reset();
else throw new ReferenceError(`${this.nodeName.toLowerCase()}: Couldn't find host element while connecting to document.`);
}
}
上调用connectedCallback()
,则可以到达<my-list>
,但是如果在<my-controller>
上调用connectedCallback()
,则只能到达<my-item>
。当我以<span>
开始搜索时,我什至无法到达<my-list>
。
即使在调用<my-item>
之后遍历DOM树,从connectedCallback()
开始也无法超越<span>
。
这是故意的吗?
为什么可以从第一个嵌套的Web组件到达外部Web组件,而 从第二个嵌套的Web组件到达第一个嵌套Web组件呢?
如何从任何嵌套级别完全访问DOM树?
答案 0 :(得分:2)
当您定义带有Shadow DOM的Custom Element内容时,您将创建一个独特的DOM树。 Shadow DOM是一个没有根元素的DocumentFragment。
因此,仅通过parentElement
属性将DOM向上移动,就无法达到其(直观的)祖先。
要访问Shadow DOM的宿主元素,请结合使用use getRootNode()
和host
。
通过<my-item>
的{{1}}方法:
connectedCallback()
如果您想获得祖先,可以尝试使用此recursive function。
答案 1 :(得分:1)
内部/子元素能够访问外部/父元素的数据通常被认为是不好的做法。
使用内部组件自定义事件(由外部组件捕获)更安全,更省心。
内部组件将调度一个事件,让外部元素知道它需要一些东西,然后外部组件可以在内部组件上调用函数或设置参数。
您可以执行以下操作:
子元素
connectedCallback() {
this.dispatch(new CustomEvent('request-service'));
}
set service(val) {
this._service = val;
}
get service() {
return this._service;
}
服务元素:
constructor() {
super();
this.addEventListener('request-service',
evt => {
evt.target.service = this.GetService(evt.target);
}
);
}
答案 2 :(得分:0)
ShadowRoot
不是元素,并且ShadowRoot
的{{1}}不是它的宿主元素。您需要照顾好他们。
parentNode