Javascript 访问作为DOM或影子DOM的web组件的父上下文

Javascript 访问作为DOM或影子DOM的web组件的父上下文,javascript,dom,polymer,web-component,shadow-dom,Javascript,Dom,Polymer,Web Component,Shadow Dom,背景: 我正在不同的环境中进行关于web组件组合的测试。特别是,我试图通过在相关组件的DOM/shadowdom中进行搜索,从另一个组件访问多个web组件,从而将它们联系起来 问题: 假设我们有一个名为x-foo的web组件,需要访问另一个x-randgen。后一个组件公开了前者使用的业务方法。为了避免两个组件之间的紧密耦合通信,我希望使用x-foo中的发现机制,通过跨DOM和shadowdom模型的搜索过程访问x-randgen。我特别指出了两种可能的情况。实例化的x-foo和x-randge

背景:

我正在不同的环境中进行关于web组件组合的测试。特别是,我试图通过在相关组件的
DOM
/
shadowdom
中进行搜索,从另一个组件访问多个web组件,从而将它们联系起来

问题:

假设我们有一个名为
x-foo
的web组件,需要访问另一个
x-randgen
。后一个组件公开了前者使用的业务方法。为了避免两个组件之间的紧密耦合通信,我希望使用
x-foo
中的发现机制,通过跨
DOM
shadowdom
模型的搜索过程访问
x-randgen
。我特别指出了两种可能的情况。实例化的
x-foo
x-randgen
都在全局上下文(index.html)中,或者它们都出现在另一个模板中,比如
x-bar
。问题在于,在每种情况下,搜索过程的实现方式应该有所不同。下面我展示了一个伪代码,用我的方法总结了我的问题。(可以在此处找到全局示例:)

聚合物('x-foo'{ ... getRandGen:函数(){ 如果() 返回文档。查询选择器('x-randgen'); 如果() 返回; } }); 问题:


如果有人能根据聚合物技术用适当的术语重新表述上述片段,我将不胜感激

jsbin中有两个bug。第一个是您想要
domReady
,而不是
ready
,因为您在内部调用了
getRandGen()
,它查询DOM。尽管如此,这也有点脆弱,因为它取决于
x-randgen
事件触发时存在的
x-foo
元素(因此如果
x-randgen
在条件模板中,它将不起作用,例如

第二个问题是
document.querySelector('x-randgen')
在ShadowDOM中找不到

这里有一点术语说明,“模板上下文”和“全局上下文”想法并不完全正确。聚合元素在其阴影根中实例化它们的
,从而建立阴影dom。阴影dom是用于隔离组件的抽象,因此它们不太可能干扰页面的其余部分,页面也不太可能干扰它们。可以跨越他对dom边界进行了阴影处理,但请注意,您可能正在深入了解其他组件的实现细节

所有这些都表明,如果你不在乎你得到了什么,即使它在一些完全不相关的组件中,这应该是可行的:
document.querySelector('x-randgen')| document.querySelector('body/deep/x-randgen')
。JSBin:


理想情况下,尽管您对
x-randgen
与您的
x-foo
的相对位置有了更好的了解,或者正如我在上文中所建议的那样,负责
x-randgen
x-foo
的组件可以明确地让它们相互了解。

您可以这样编写问题函数:

    getRandGen: function () {
      var root = this;
      while (root.parentNode) {
        root = root.parentNode;
      }
      return root.querySelector('x-randgen');
    }

其他解决方案可以使用单态模式(罕见)或适当的控制器(常见)

monostate的想法是,一个特定的元素表达了一个通向共享状态的管道(即
max
值)。只要需要访问共享状态,就只需创建一个访问器元素

控制器的思想是,该元素会引发一个事件,请求
randgen
实用程序。某个祖先(控制器)处理该事件并提供资源。这是一种依赖关系管理,对设计灵活性有很大帮助


您是否考虑过让使用这两个元素的代码将它们彼此连接起来?类似于
。通常最好在可能的情况下明确说明这类事情。谢谢Peter,我正在研究web组件环境中的不同组合模型。您需要的解决方案建议与直接通信很好地结合在一起,我已经成功地测试了它,但是我认为松散耦合的通信被用于其他情况。一般来说,我认为它是一个有用的工具,有一个方法来访问父上下文,无论是全局的还是模板的。实际上,在我看来,ACC的代码。essing父上下文不应该依赖于wc实例所在的上下文。我之所以推动显式绑定,是因为当它出错时,有一种方法可以纠正或覆盖它。例如,如果有多个
x-randgen
元素,或者您想根据情况使用不同的元素。在无论如何,足够抽象的担忧,我想我已经发现了为什么这对你不起作用。在我看来,松散和明确的沟通都是有价值的。你可以使用下面描述的单态和/或控制器技术,在大多数情况下吃你的蛋糕。例如,控制器可以很容易理解元素之间的明确协调,而单个元素可以简单地提出问题,而不知道答案来自何处。更极端的松耦合可以通过
聚合物信号来实现(即将成为
核心信号
),这是一个通用的发布子系统,但应该非常谨慎地使用。Fwiw,还请注意,您不需要从属性中刮取
max
属性。这是自动发生的。+1对于使用事件冒泡的想法,这真是太好了。Fwiw,首先使用这种搜索方法很难定义;th这就是为什么我们更喜欢气泡而不是控制器技术:fir
    getRandGen: function () {
      var root = this;
      while (root.parentNode) {
        root = root.parentNode;
      }
      return root.querySelector('x-randgen');
    }