You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Polymer中如何利用dom-repeat循环渲染数组指定的自定义元素?

实现动态遍历自定义元素标签的方案

Great question! Unfortunately, the syntax you tried (<[[item]]></[[item]]>) won't work directly because Polymer's template parser doesn't dynamically replace tag names like that. But there are a couple of solid ways to achieve what you're aiming for:

1. 针对扩展内置元素的自定义元素(使用is属性)

If your custom elements extend native HTML elements (like div or span), you can use the is attribute to bind the dynamic tag name. This works because it's part of the custom elements spec for built-in extensions.

First, define your custom element like this (extending a native element):

class MyElement1 extends HTMLDivElement {
  constructor() {
    super();
    this.textContent = "I'm my-element1!";
  }
}
customElements.define('my-element1', MyElement1, { extends: 'div' });

Then in your Polymer template, use dom-repeat with the is attribute:

<template is="dom-repeat" items="[[blocks]]">
  <div is="[[item]]"></div>
</template>

2. 针对独立自定义元素(结合模板与JavaScript)

For custom elements that don't extend native elements (the more common case), you'll need to pair dom-repeat with a bit of JavaScript to dynamically create and insert the elements. This is the most reliable approach for standard custom elements.

Here's a complete example:

<dom-module id="element-wrapper">
  <template>
    <!-- Use dom-repeat to create containers for each dynamic element -->
    <template is="dom-repeat" items="[[blocks]]" id="blocksRepeat">
      <div class="element-container"></div>
    </template>
  </template>
  <script>
    class ElementWrapper extends Polymer.Element {
      static get is() { return 'element-wrapper'; }
      
      static get properties() {
        return {
          blocks: {
            type: Array,
            value: () => ['my-element1', 'my-element2', 'my-element3']
          }
        };
      }

      connectedCallback() {
        super.connectedCallback();
        // Wait for dom-repeat to render containers before adding elements
        this.$.blocksRepeat.addEventListener('dom-change', this._renderDynamicElements.bind(this));
      }

      _renderDynamicElements() {
        const containers = this.shadowRoot.querySelectorAll('.element-container');
        
        containers.forEach((container, index) => {
          const tagName = this.blocks[index];
          // Ensure the custom element is registered before creating it
          if (customElements.get(tagName)) {
            const element = document.createElement(tagName);
            container.appendChild(element);
          } else {
            console.warn(`Custom element "${tagName}" is not registered yet!`);
          }
        });
      }

      // Add an observer if your blocks array might change dynamically
      static get observers() {
        return ['_onBlocksChange(blocks.splices)'];
      }

      _onBlocksChange() {
        // Clear existing elements first
        const containers = this.shadowRoot.querySelectorAll('.element-container');
        containers.forEach(container => container.innerHTML = '');
        // Re-render the updated elements
        this._renderDynamicElements();
      }
    }
    customElements.define(ElementWrapper.is, ElementWrapper);
  </script>
</dom-module>

Key Notes:

  • Always make sure your custom elements are registered (via customElements.define()) before trying to create them dynamically. If elements load asynchronously, you might need to use customElements.whenDefined(tagName) to wait for them.
  • The dom-change event ensures we only try to add elements after the dom-repeat has finished rendering its containers.
  • The observer for blocks.splices handles cases where your array is updated (items added/removed) by re-rendering the elements.

内容的提问来源于stack exchange,提问作者Andrew Noblet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:43:28