【问题标题】:Angular Material table with subrows (nested cells) of different heights具有不同高度的子行(嵌套单元格)的角材料表
【发布时间】:2018-08-02 20:31:34
【问题描述】:

我想创建一个表格,其中包含模仿子行的嵌套单元格。如果每个单元格的内容不超过嵌套单元格 (A) 的 min-height 属性值,则它工作正常。

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

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

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

【问题讨论】:

  • 谢谢,但我需要单元格高度才能根据其内容增长。在您的示例中,单元格高度是固定的。
  • 是的,我后来注意到了......这就是为什么我没有把它作为答案,只是一个快速的想法
  • @Vega 不,我需要单元格内的所有内容都可见。在您的解决方案中,内容在高度超过 60 像素后被剪裁。

标签: angular css flexbox angular-material


【解决方案1】:

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

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

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

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

【讨论】:

  • 谢谢,使用指令似乎是最优雅的解决方案
猜你喜欢
  • 2016-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多