具有不同高度的子行(嵌套单元)的角材料表

Wil*_*nik 1 css css3 flexbox angular-material angular

我想用嵌套单元格模拟子行创建一个表。如果每个单元格的内容不超过嵌套单元格(A)的min-height属性值,则该方法工作正常。

不幸的是,当超过此值时,表会崩溃(B)。有没有简单的方法可以正确对齐嵌套单元格以获得像(C)这样的表?

代码:https//stackblitz.com/edit/angular-aejwfm

img

(*)我知道我们可以使用javascript将代表某个子行的所有单元格的高度设置为max(该子行中所有单元格的高度),但是我更喜欢纯HTML / CSS / Angular解决方案。

Hir*_*ekh 6

一种可能的解决方案是,您可以创建一个指令,该指令为每行查找一个具有max-height的单元格,并将相同的高度应用于该行的所有单元格。

但是,您正在渲染数据列VISE,因此您需要向指令提供一些信息,指令可以使用这些信息来标识单个行的单元格。

我已经更新了您的代码以达到预期的效果。

https://stackblitz.com/edit/angular-aejwfm-6htvuk

这是我对您的演示所做的更改的简要说明:

创建一个将book对象作为输入接受的指令。本书的对象将帮助我们识别单行的单元格。

@Directive({
  selector: '[matchCellHeight]'
})
export class MatchCellHeightDirective {

  @Input() matchCellHeight: any;

  constructor(private el: ElementRef) { 

  }
}
Run Code Online (Sandbox Code Playgroud)

然后将此指令绑定到模板中的每个单元格元素。

    <ng-container matColumnDef="title">
      <mat-header-cell *matHeaderCellDef> Title </mat-header-cell>
      <mat-cell *matCellDef="let genre">
        <mat-cell [matchCellHeight]='book' *ngFor="let book of genre.books"> //bind matchCellHeight to each cell
           {{book.title}} 
        </mat-cell>
      </mat-cell>
    </ng-container>

    <ng-container matColumnDef="pages">
      <mat-header-cell *matHeaderCellDef> Pages </mat-header-cell>
      <mat-cell *matCellDef="let genre">
        <mat-cell [matchCellHeight]='book' *ngFor="let book of genre.books">
           {{book.pages}} 
        </mat-cell>
      </mat-cell>
    </ng-container>
Run Code Online (Sandbox Code Playgroud)

现在,我们需要将每个单元格的参考存储在某个位置,以便可以将匹配高度逻辑应用于每个单元格。为此,我创建了一个服务并将其注入指令中。

@Injectable()
export class MatchCellHeightService{
  cells:{el:ElementRef,data:any}[] = [];
  constructor(){

  }

  findUniqueBooks():any[]{
    return this.cells.map(currCell => currCell.data).reduce(
      (acc,curr) => {
        if(acc){
          if(acc.indexOf(curr) == -1){
            acc.push(curr);
          }
        }else{
          acc = [].push(curr)
        }
        return acc;
      },[]
    )
  }

  matchHeight(){
    /* first find all the unique books*/
    let books = this.findUniqueBooks();


    for(let i = 0; i < books.length ; i++){
      let currbook = books[i];

      /*for each book find cells that containins this book object info
        (in this demo each row is containng info about one book there for we are using book object 
        to identify cells of each row)
      */
      let bookCells:{el:ElementRef,data:any}[] = [];

        for(let j = 0; j < this.cells.length ; j++){
          let currCell = this.cells[j];
          if(currCell.data == currbook){
            bookCells.push(currCell);
          }
        }

        /*once we have the array of cells which are of same row apply the match height logic*/
        bookCells.forEach(val => val.el.nativeElement.style.height = 'initial');
        let maxHeight = Math.max(...bookCells.map(val => val.el.nativeElement.offsetHeight));
        bookCells.forEach(currCell => {
          currCell.el.nativeElement.style.height = maxHeight+'px';
        })
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我希望这将有所帮助。而且我还发现了另一种实现相同功能的指令实现。这是链接。 https://scotch.io/tutorials/sensitive-equal-height-with-angular-directive