Angular Material表,包含不同高度的子行(嵌套单元格)

时间:2018-02-22 20:38:27

标签: css angular css3 flexbox angular-material

我想用嵌套单元格创建一个模仿子行的表。如果每个单元格的内容不超过嵌套单元格(A)的最小高度属性值,则它可以正常工作。

不幸的是,当超过此值时,表格会崩溃(B)。是否有任何简单的*方法可以正确对齐嵌套单元格以获得类似(C)的表格?

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

img

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

1 个答案:

答案 0 :(得分:4)

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

但是您正在渲染数据列虎钳,因此您需要向指令提供一些信息,使用该指令可以识别单行的单元格。

我已更新您的代码以获得所需的结果。

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

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

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

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

  @Input() matchCellHeight: any;

  constructor(private el: ElementRef) { 

  }
}

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

    <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>

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

@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';
        })
    }
  }
}

我希望这会有所帮助。我还发现了一个执行相同工作的指令的另一个实现。这是链接。 https://scotch.io/tutorials/responsive-equal-height-with-angular-directive