Vanilla Custom Element repeater for

后端 未结 1 847
臣服心动
臣服心动 2020-12-17 03:54

I\'m currently trying to implement a repeater WebComponent to allow the company to easily create front-end without depending on any framework (deci

相关标签:
1条回答
  • 2020-12-17 04:16

    Solution 1

    Put the repeater around your elements. Ex. for a minimal <data-repeater> custom element :

    customElements.define('data-repeater', class extends HTMLElement 
    {
      connectedCallback() 
      {
        const parent = this.firstElementChild
        const data = JSON.parse(this.dataset.values)
    
        const interpolate = obj => parent.innerHTML.replace(
          /\${(\w+)}/g,
          (match, key) => obj[key]
        )
    
        parent.innerHTML = data.map(interpolate).join('')
      }
    })
    <data-repeater data-values='[{"label": "Item 1", "id":1}, {"label": "Item 2", "id": 2}]'>
      <ul>
        <li id="${id}">${label}</li>
      </ul>
    </data-repeater>
    
    <data-repeater data-values='[{"name": "option 1", "value":1}, {"name": "option 2", "value": 2}]'>
      <select>
          <option value="${value}">${name}</option>
      </select>
    </data-repeater>

    Solution 2

    Use customized built-in elements. You need to choose a new name for each standard element you want to extend, but you can reuse internally a unique base class to render the elements:

    <select is="repeat-option" data-values="[...]">
       <option value="${value}">${name}</option>
    </select>
    

    customElements.define('select-repeater', class extends HTMLSelectElement {
      connectedCallback() { render(this) }
    }, { extends: 'select' })
    
    customElements.define('ul-repeater', class extends HTMLUListElement {
      connectedCallback() { render(this) }
    }, { extends: 'ul' })
    
    function render(view) {
      const data = JSON.parse(view.dataset.values)
    
      const interpolate = obj => view.innerHTML.replace(
        /\${(\w+)}/g,
        (match, key) => obj[key]
      )
    
      view.innerHTML = data.map(interpolate).join('')
    }
    <script src="https://rawgit.com/WebReflection/document-register-element/master/build/document-register-element.js"></script>
    
    
    <ul is="ul-repeater" data-values='[{"label": "Item 1", "id":1}, {"label": "Item 2", "id": 2}]'>
        <li id="${id}">${label}</li>
    </ul>
    
    
    <select is="select-repeater" data-values='[{"name": "option 1", "value":1}, {"name": "option 2", "value": 2}]'>
    		<option value="${value}">${name}</option>
    </select>


    If the rendering is very different depending on the element you could decide to create a class for rendering and to use derived classes for each type fo rendering ( select, ul, tr, td ), like in this example for tables.

    0 讨论(0)
提交回复
热议问题