Angular Material Table rowspan columns based on dataSource object array property size

前端 未结 4 1927
梦如初夏
梦如初夏 2020-12-15 23:11

Even now in version 7.2 of Angular Material, I can\'t seem to find examples on how to use rowspan on mat-table and keep the component functionality.

This is how far

4条回答
  •  误落风尘
    2020-12-15 23:39

    Well, it seems that material table has no api documentation for it, I could not find any trick to do this too, But we can twick the our data to support this, as per your second example we can reform the data to new json and we can get our expected result.

    Step 1 :

        const originalData = [
          { id: 1, name: 'Hydrogen', weight: 1.0079, descriptions: ['row1', 'row2'] },
          { id: 2, name: 'Helium', weight: 4.0026, descriptions: ['row1', 'row2', 'row3'] },
          { id: 3, name: 'Lithium', weight: 6.941, descriptions: ['row1', 'row2'] },
          { id: 4, name: 'Beryllium', weight: 9.0122, descriptions: ['row1', 'row2', 'row3'] },
          { id: 5, name: 'Boron', weight: 10.811, descriptions: ['row1'] },
          { id: 6, name: 'Carbon', weight: 12.0107, descriptions: ['row1', 'row2', 'row3'] },
          { id: 7, name: 'Nitrogen', weight: 14.0067, descriptions: ['row1'] },
          { id: 8, name: 'Oxygen', weight: 15.9994, descriptions: ['row1'] },
          { id: 9, name: 'Fluorine', weight: 18.9984, descriptions: ['row1', 'row2', 'row3'] },
          { id: 10, name: 'Neon', weight: 20.1797, descriptions: ['row1', 'row2', 'row3'] },
        ]; //original data
    
        const DATA = originalData.reduce((current, next) => {
          next.descriptions.forEach(b => {
            current.push({ id: next.id, name: next.name, weight: next.weight, descriptions: b })
          });
          return current;
        }, []);//iterating over each one and adding as the description 
        console.log(DATA)
    
        const ELEMENT_DATA: PeriodicElement[] = DATA; //adding data to the element data
    

    Step 2

    this will be as it is as your second stackblitz link.

     getRowSpan(col, index) {    
        return this.spans[index] && this.spans[index][col];
      }
    

    Step 3

    as it is as per your second link

      constructor() {
        this.cacheSpan('Priority', d => d.id);
        this.cacheSpan('Name', d => d.name);
        this.cacheSpan('Weight', d => d.weight);
      }
    
      /**
       * Evaluated and store an evaluation of the rowspan for each row.
       * The key determines the column it affects, and the accessor determines the
       * value that should be checked for spanning.
       */
      cacheSpan(key, accessor) {
        for (let i = 0; i < DATA.length;) {
          let currentValue = accessor(DATA[i]);
          let count = 1;
    
          // Iterate through the remaining rows to see how many match
          // the current value as retrieved through the accessor.
          for (let j = i + 1; j < DATA.length; j++) {
            if (currentValue != accessor(DATA[j])) {
              break;
            }
    
            count++;
          }
    
          if (!this.spans[i]) {
            this.spans[i] = {};
          }
    
          // Store the number of similar values that were found (the span)
          // and skip i to the next unique row.
          this.spans[i][key] = count;
          i += count;
        }
      }
    

    Step 4

    Using index to pass down to rowspan and hiding the rows where it doesn't needed

        
             Priority 
            
             {{ data.id }} 
        
    
        
             Name 
            
             {{ data.name }} 
        
    
        
             Weight 
            
             {{ data.weight }} 
        
    
        
             Descriptions 
             {{ data.descriptions }} 
        
    
        
         
    
    
    
    

    Here is the demo

提交回复
热议问题