Create a Custom Element with different sub-types

前端 未结 2 960
长发绾君心
长发绾君心 2020-12-11 08:38

I am currently implementing a data-table element using custom elements (web components). The table can have different types of cells (text, number, date, etc) that are used

2条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-12-11 09:26

    NB: This answer is separeted from the other as it's quite extensive by itself and totally independant.

    If you use Autonomous Custom Elements (i.e. custom tags) with a (optionnal) type attribute:

    
            
            1       
            An
            20
        
    
    

    ...you could use the MVC pattern:

    • define a class for the generic cell View (and/or Model)
    • define a subclass for the specialized Views (Date, Number, String)

    Example with generic and string view:

    class CellView {
        constructor ( view ) {
            this.view = view
        }
        render () {
            //default rendering
        }       
    }
    
    //String View
    class CellStringView extends CellView {
        render () {
            console.info( 'special rendering', this.view )
            this.view.innerHTML = '"' + this.view.textContent + '"'
        }
    }
    

    In the custom element definition (which can be viewed as the Controller):

    • on creation, instantiate the View (or Model).
    • when you want to render the cell (or process the data), call the (overridden, or not) method of the View (or Model).

    Example with a Custom Element v1 class:

    class CellElement extends HTMLElement {
        constructor () {
            super()
            //create cell
            switch ( this.getAttribute( 'type' ) )
            {
                case 'string': 
                    this.view = new CellStringView( this ) 
                    break
    
                default:
                    this.view = new CellView( this )
            }
        }
        connectedCallback () {
            //render cell
            this.view.render()
        }
    } 
    

    Below is a live snippet:

    //View (MVC View)
    class CellView {
      constructor(view) {
        this.view = view
      }
      render() {}
    }
    
    //String View
    class CellStringView extends CellView {
      render() {
        console.info('special rendering', this.view)
        this.view.innerHTML = '"' + this.view.textContent + '"'
      }
    }
    
    //Element (MVC controller)
    class CellElement extends HTMLElement {
      constructor() {
        super()
        //create cell
        switch (this.getAttribute('type')) {
          case 'string':
            this.view = new CellStringView(this)
            break
    
          default:
            this.view = new CellView(this)
        }
      }
      connectedCallback() {
        //render cell
        this.view.render()
      }
    }
    customElements.define('data-cell', CellElement)
    data-table {
      display: table ;
      border-collapse: collapse ;
      border: 1px solid gray ;
    }
    
    data-row {
      display: table-row ;
    }
    
    data-cell {
      display: table-cell ;
      border: 1px solid #ccc ;
      padding: 2px ;
    }

    Custom Table v1

    Id Name Age 1 An 20 2 Bob 31

提交回复
热议问题