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

How to inject template using slot with data-binding in Polymer2

我想使用 <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" 的概念来实现这一点。在此先感谢您的任何反馈!

数据绑定默认绑定在绑定的当前范围内。如果你想改变范围,你必须把你的标记放在一个 <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>