如何在Polymer2中使用带数据绑定的插槽注入模板

时间:2017-06-07 12:12:47

标签: polymer web-component polymer-2.x

我想使用<slot>插入点从父组件向子组件注入渲染模板。注入的模板包含子组件属性的数据绑定(在本例中为my-child.data)。

<dom-module id="my-parent">
  <template>
    <my-child>
      <template>
        <div>Child's data property: [[data]]</div>
      </template>
    </my-child>
  </template>
  ...

渲染子组件基本上如下所示:

<dom-module id="my-child">
  <template>
    <header></header>
    <slot></slot>
    <footer></footer>
  </template>

  <script>
    class MyChild extends Polymer.Element {
      static get is() { return 'my-child'; }
      static get properties() {
        return {
          data: { ... }
        };
      }
      ...

我不确定Polymer2是否可以实现这一点。 Vue2有一个名为"scoped slot"的概念来实现这一目标。提前感谢您的任何反馈!

1 个答案:

答案 0 :(得分:8)

默认情况下,数据绑定绑定在绑定的当前范围内。如果您希望更改范围,则必须将标记放在<template>标记内并在其他范围内标记。

问题中的HTML代码已经正常 - 您实际上将轻型DOM包装在<template>内,但是您错误地使用了<template>。您必须使用<slot>,但必须手动标记该模板并将其插入my-child元素的影子DOM内的某处。

这里有一个关于如何实现这个目标的工作演示:http://jsbin.com/loqecucaga/1/edit?html,console,output

我甚至已将data属性绑定添加到input元素,以证明属性更改也会影响标记模板。

标记相对简单,在connectedCallback方法内完成:

var template = this.querySelector('template');
this.__instance = this._stampTemplate(template);
this.$.content.appendChild(this.__instance);

标记的模板放在占位符div元素中,放在my-child模板中的某个位置:

<div id="content"></div>

总结一下,这是演示中的完整代码:

<link href="polymer/polymer-element.html" rel="import"/>
<link href="polymer/lib/mixins/template-stamp.html" rel="import"/>

<dom-module id="my-parent">
  <template>
    <my-child>
      <template>
        <div>Child's data property: [[data]]</div>
      </template>
    </my-child>
  </template>

  <script>
    class MyParent extends Polymer.Element {
      static get is() { return 'my-parent'; }
    }

    window.customElements.define(MyParent.is, MyParent);
  </script>
</dom-module>

<dom-module id="my-child">
  <template>
    <header>Header</header>
    <div id="content"></div>
    <footer>Footer</footer>
    <input type="text" value="{{data::input}}" />
  </template>

  <script>
    class MyChild extends Polymer.TemplateStamp(Polymer.Element) {
      static get is() { return 'my-child'; }
      static get properties() {
        return {
          data: {
            type: String,
            value: 'Hello, World!'
          },
        };
      }

      connectedCallback() {
        super.connectedCallback();

        var template = this.querySelector('template');
        this.__instance = this._stampTemplate(template);
        this.$.content.appendChild(this.__instance);
      }
    }

    window.customElements.define(MyChild.is, MyChild);
  </script>
</dom-module>

<my-parent></my-parent>