访问Web组件的父上下文是DOM或Shadow DOM

时间:2014-05-30 00:17:33

标签: javascript dom polymer web-component shadow-dom

上下文:

我正在针对不同环境中的Web组件组合进行测试。特别是我试图通过在所涉及组件的DOM / Shadow DOM内的搜索过程访问其中一个Web组件,从而关联多个Web组件。

问题:

假设我们有一个名为x-foo的网络组件,需要访问另一个x-randgen。后一个组件公开了前者使用的业务方法。为了避免两个组件之间的紧密耦合通信,我想在x-foo中使用发现机制通过x-randgenDOM模型的搜索过程访问Shadow DOM。特别是我确定了两种可能的情况。实例化的x-foox-randgen都在全局上下文(index.html)中,或者它们都出现在另一个模板中,比如x-bar。问题是搜索过程应该在每种情况下以不同的方式实现。接下来,我用我的方法总结了一个伪代码,实质上是我的问题。 (可在此处找到全局示例:http://jsbin.com/qokif/1/

    Polymer('x-foo', {
       ...
       getRandGen: function () {
          if (<<x-foo & x-randgen are in the global context>>)
             return document.querySelector('x-randgen');
          else if (<<x-foo & x-randgen are in a template>>)
             return <<the x-randgen tag within the template>>;
       }
    });

问题:

如果有人可以根据聚合物技术以适当的方式重新制作上面的片段,我将不胜感激。

2 个答案:

答案 0 :(得分:7)

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

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

http://jsbin.com/xufewi/1/edit

可以使用单稳态模式(稀有)或适当的控制器(常见)来制作其他解决方案。

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

控制器的想法是元素冒泡请求randgen实用程序的事件。一些祖先(控制器)处理事件并提供资源。这是一种依赖管理,对设计灵活性非常有用。

http://jsbin.com/tudow/1/edit

答案 1 :(得分:0)

你的jsbin中有两个bug。首先,您需要domReady,而不是ready,因为您在内部调用了getRandGen(),它会查询DOM。即使这有点脆弱,因为它取决于x-randgen的domReady事件触发时存在的x-foo元素(因此如果x-randgen处于document.querySelector('x-randgen')状态,它将无效条件模板,例如

第二个问题是<x-randgen>在ShadowDOM中找不到<template>

这里有一些术语说明。 “模板背景”和“全球背景”的想法并不完全正确。聚合物元素在它们的阴影根中实例化它们的x-randgen,它们建立了一个阴影dom。阴影dom是隔离组件的抽象,因此它们不太可能干扰页面的其余部分,并且页面不太可能干扰它们。可以跨越阴影dom边界,但只要知道您可能正在深入了解其他组件的实现细节。

所有这一切都表明,如果你不关心document.querySelector('x-randgen') || document.querySelector('body /deep/ x-randgen')你得到什么,即使它在一些完全不相关的组件中,这应该有效:x-randgen。 JSBin:http://jsbin.com/goqikire/1/edit

理想情况下,您可以更好地了解x-foo相对于x-randgen的相对位置,或者正如我在上面建议的那样,负责x-foo和{{{1}}的组件{1}}可以明确地让他们彼此了解。