3

I'd like to use dom-repeat to wrap a bunch of child nodes in <li> tags. The problem is, the nodes I want to repeat are custom elements themselves, inserted via a slot, and it seems that dom-repeat only takes data passed via attributes.

What I want to do is:

<dom-module id="my-custom-element">
  <template>
    <section>
      ...
      <ul>
        <dom-repeat items="{{ TOP-LEVEL NODES IN LIST SLOT }}">
          <template>
            <li>{{ item }}</li>
          </template>
        </dom-repeat>
      </ul>
    </section>
  </template>
</dom-module>

And using it:

<my-custom-element>
  <ul slot="LIST">
    <my-other-custom-element></my-other-custom-element>
    <my-other-custom-element></my-other-custom-element>
    <my-other-custom-element></my-other-custom-element>
  </ul>
</my-custom-element>
Elise
  • 5,086
  • 4
  • 36
  • 51
  • 1
    I'm not sure whether this is similar to what you want to do, but I've build a long time ago a kinda similar contraption, if you will, here it is: https://github.com/nicholaswmin/editable-list#how-it-works-internally. What I do is basically take a `slot` (defined externally) and repeat it in a `dom-repeat` that lives *inside* the element. Keep in mind that the project I've sent was built on a pre-release version of Polymer 2.x so I'm not entirely sure it still works as intended. – nicholaswmin Apr 29 '18 at 20:50

1 Answers1

1

I don't think this is the best Polymer way to do it, however it works:

  <x-foo>
    <ul slot="list">
      <div> hi </div>
      <div> hello </div>
      <div> bye </div>
    </ul>
  </x-foo>

  <dom-module id="x-foo">
    <template>
      <h2> The raw slotted items </h2>
      <slot name="list" id="list"></slot>
        <h2> The slotted list items wrapped with 'li' </h2>
      <ul id="styledList"></ul>
    </template>
  </dom-module>

Here is the trick:

 class XFoo extends Polymer.Element {
    static get is() { return 'x-foo'; }

    static get properties() {
      return {
        items: {
          type: Array,
          value: function() {
            return [1, 2, 3, 4]
          }
        }
      };
    }

    connectedCallback() {
      super.connectedCallback();
      this.$.list.addEventListener('slotchange', (e) => this.bindSlottedItems() );
    }

    bindSlottedItems() {
        let items = this.$.list.assignedNodes({flatten: true})[0].childNodes;
        items = [].slice.call(items)
        this.$.styledList.innerHTML = items.filter((item) => item.outerHTML).map((item) => {
          return `<li> ${item.outerHTML} </li>`
        }).join('');
    }
  }
  customElements.define(XFoo.is, XFoo);

https://codepen.io/MWalid/pen/aGJRWy

Walid Ammar
  • 4,038
  • 3
  • 25
  • 48