Polymer 以模板作为内容的聚合物自定义元素

Polymer 以模板作为内容的聚合物自定义元素,polymer,Polymer,在下面的代码中,当我试图通过编程方式访问模板栏或在Chrome中检查DOM时,模板栏的内容“Foo”总是空的。有人能解释一下原因吗 通常,如何将外部元素中定义的模板提供给内部元素,以便内部元素可以访问内容并有条件地克隆或导入该内容 我使用的是聚合物0.4.2 <polymer-element name="x-inner" noscript> <!-- How can I access the content "Foo" of <template&g

在下面的代码中,当我试图通过编程方式访问模板栏或在Chrome中检查DOM时,模板栏的内容“Foo”总是空的。有人能解释一下原因吗

通常,如何将外部元素中定义的模板提供给内部元素,以便内部元素可以访问内容并有条件地克隆或导入该内容

我使用的是聚合物0.4.2

<polymer-element name="x-inner" noscript>
    <!--
        How can I access the content "Foo" of <template>Foo</template>,
        So that I can import/clone it here?

        Using <content> moves the template from x-outer to x-inner,
        but the template's .content property is empty, instead of 'Foo' as I expected.
     -->
    <content></content>
</polymer-element>

<polymer-element name="x-outer" noscript>
    <template>
        <x-inner>
            <!--
                How can I pass a template to a custom element?
                I don't want the contents of this template to be rendered
                here in x-outer, but instead conditionally rendered by x-inner
             -->
            <template id="bar">Foo</template>
        </x-inner>
    </template>
</polymer-element>

<x-outer></x-outer>

这个主题可能很复杂,下面是一些让您开始学习的内容

(这是对此答案的第三次更新,确认了上面关于“复杂”=p的位)

Polymer包括
TemplateBinding.js

TemplateBinding.js
库为
注入了许多功能,包括对模型的数据绑定、条件戳记和通过阵列的复制/迭代。它还添加了一个功能,使克隆的嵌套模板不会复制它们自己的内容,从而防止在迭代时可能出现的无用节点爆炸。相反,
TemplateBinding.js
在克隆的嵌套模板中创建对原始内容模板的引用。结果是,如果您使用的是
TemplateBinding.js
,则应使用
template.createInstance()
API以获得最佳结果

现在,在不使用
TemplateBinding.js
的情况下使用原始模板时,只需使用
var nodes=document.importNode(template.content,true)
即可为模板加盖戳记。当然,在这种情况下,您不会得到嵌套模板复制优化(这可能很重要,也可能无关紧要)

注:

  • 我从
    模板,因为它没有任何用途。下面的代码提取 模板直接脱离光dom,并将实例标记到 影子根
  • x-outer
    之前声明
    x-inner
    ,因为后者依赖于前者
  • 示例代码:

    <x-outer></x-outer>
    
    <polymer-element name="x-inner">
    <template>
    </template>
    <script>
    
      Polymer({
        domReady: function() {
          this.renderTemplate();
        },
        renderTemplate: function() {
    
          // note: this only works if `template` is a true child of `this`
          // (as opposed to projected) 
          var template = this.querySelector('template');
    
          // use createInstance from TemplateBinding.js library API
          this.shadowRoot.appendChild(template.createInstance());
    
          /* 
          // this would work for raw templates, but Polymer includes TemplateBinding.js
          this.shadowRoot.appendChild(stampTemplate(template));
          */
    
          /* 
          // if you don't know whether TemplateBinding.js exists or not,
          // you could do something like this (see stampTemplate definition below)
          this.shadowRoot.appendChild(stampTemplate(template));
          */
    
          /*
          // this way uses the binding feature of TemplateBinding.js
          template.setAttribute('bind', '');
          template.model = { /* some data */ };
          */
        }
      });
    
      // use best available API
      function stampTemplate(template) {
        if (template.createInstance) {
          return template.createInstance();
        } else {
          return document.importNode(template.content, true);
        }
      }
    
    </script>
    </polymer-element>
    
    <polymer-element name="x-outer" noscript>
    <template>
    
      <x-inner>
        <template id="bar">Foo</template>
      </x-inner>
    
    </template>
    </polymer-element>
    
    
    聚合物({
    domReady:function(){
    this.renderTemplate();
    },
    renderTemplate:function(){
    //注意:只有当“template”是“this”的真正子级时,此选项才有效`
    //(与预计相反)
    var template=this.querySelector('template');
    //使用TemplateBinding.js库API中的createInstance
    this.shadowRoot.appendChild(template.createInstance());
    /* 
    //这将适用于原始模板,但Polymer包含TemplateBinding.js
    this.shadowRoot.appendChild(stampTemplate(模板));
    */
    /* 
    //如果您不知道TemplateBinding.js是否存在,
    //您可以这样做(参见下面的stampTemplate定义)
    this.shadowRoot.appendChild(stampTemplate(模板));
    */
    /*
    //这种方式使用TemplateBinding.js的绑定功能
    setAttribute('bind','');
    template.model={/*一些数据*/};
    */
    }
    });
    //使用可用的最佳API
    函数stampTemplate(模板){
    if(template.createInstance){
    返回template.createInstance();
    }否则{
    返回单据.importNode(template.content,true);
    }
    }
    福
    

    感谢您的详细回答,特别是说明了基本HTML模板和Polymer模板之间的差异。我想我会仔细看看TemplateBinding.js的内部结构