Как внедрить шаблон, используя слот с привязкой данных в 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 имеет концепцию, называемую "слотом с полями ", чтобы достичь этого. Заранее спасибо за любые отзывы!

1 ответ

Решение

Привязка данных по умолчанию связана с текущей областью привязки. Если вы хотите изменить область действия, вы должны поместить разметку внутри <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>
Другие вопросы по тегам