且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:1970-01-01 07:55:12

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

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

我已更新您的代码以达到预期的结果.

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

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

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

@Directive({选择器:'[matchCellHeight]'})导出类 MatchCellHeightDirective {@Input() matchCellHeight: 任意;构造函数(私有 el:ElementRef){}}

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

 <mat-h​​eader-cell *matHeaderCellDef>标题</mat-h​​eader-cell><mat-cell *matCellDef="let 类型"><mat-cell [matchCellHeight]='book' *ngFor="let book ofgenre.books">//将matchCellHeight绑定到每个单元格{{书名}}</mat-cell></mat-cell></ng-容器><ng-container matColumnDef="pages"><mat-h​​eader-cell *matHeaderCellDef>页面</mat-h​​eader-cell><mat-cell *matCellDef="let 类型"><mat-cell [matchCellHeight]='book' *ngFor="let book ofgenre.books">{{book.pages}}</mat-cell></mat-cell></ng-容器>

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

@Injectable()导出类 MatchCellHeightService{单元格:{el:ElementRef,data:any}[] = [];构造函数(){}findUniqueBooks():any[]{返回 this.cells.map(currCell => currCell.data).reduce((acc,curr) =>{如果(ACC){if(acc.indexOf(curr) == -1){acc.push(curr);}}别的{acc = [].push(curr)}返回acc;},[])}匹配高度(){/* 首先找到所有唯一的书*/让书籍 = this.findUniqueBooks();for(let i = 0; i  val.el.nativeElement.style.height = 'initial');让 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

I would like to create a table with nested cells imitating subrows. It works fine if content of every cell does not exceed min-height property value of nested cell (A).

Unfortunately when this value is exceeded the table breaks down (B). Is there any simple* way to align nested cells properly to obtain table like (C)?

code: https://stackblitz.com/edit/angular-aejwfm

(*) I know that we can use javascript to set height of all cells representing certain subrow to max(heights of all cells from that subrow) but I would prefer pure HTML/CSS/Angular solution.

One possible solution is you can create one directive that finds a cell with max-height for each row and apply the same height to all the cell of that row.

But you are rendering data column vise so you need to provide some information to the directive using which the directive can identify cells of a single row.

I have updated your code to achieve the desired result.

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

here is the brief explanation of the changes I have done to your demo:

create one directive which accepts the book object as Input. This book object will help us to identify cells of single row.

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

  @Input() matchCellHeight: any;

  constructor(private el: ElementRef) { 

  }
}

then bind this directive to each cell element in your template.

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

Now we need to store reference of each cell somewhere so that we can apply our match height logic on each cell. for that I have created one service and injected it in the directive.

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

I hope this will help. And I have also found another implementation of a directive that does the same job. Here is the link for that. https://scotch.io/tutorials/responsive-equal-height-with-angular-directive