表Div的范围已超出父Div的范围,但应适应大小

时间:2018-11-20 09:41:11

标签: javascript html css angular

我想创建一个表组件,其中在滚动时,表的侧面和头部的索引仅沿各自的方向移动,到目前为止效果很好。

但是,如果我现在将数据添加到数据表中,则该表将超出父Div。我不要数据表应仅与父div中的空间一样大,其余应可滚动。

我收到的有关此信息的信息建议将父div设置为display: table或将height设置为100%,但不幸的是,它不能按预期工作。

http://example.com/rest/api/latest/projects/PROJECT_1/repos/repo_1/browse/README.md

表组件模板

<div class="table-head">
   <h4>{{tablehead}}</h4>
</div>
<app-index-header [numbers]="generateIndexHeadNumbers 
                  [leftMargin]="getHeaderMargin()"
                  [cellWidths]="headerCellWidth">
</app-index-header>
<div class="table-body">
   <app-index-side [numbers]="generateIndexSideNumbers()"   
                   [cellHeight]="sideCellHeight">
   </app-index-side>
   <div #scroll class="scroll" (scroll)="onScroll()">
       <div class="table-rows" *ngIf="rows.length !== 0">
           <div *ngFor="let row of rows; let i = index;" class="table-row">
               <div *ngFor="let cell of row" class="table-cell">{{cell}</div>
           </div>
       </div>
       <div *ngIf="rows.length === 0">
           No Data
       </div>
   </div>
</div>

样式

:host{
   display: block;
   background-color: #F2F2F2;
   height: inherit;
 }
 .table-head h4{
     display: block;
     margin-top: 0;
 }
 app-index-header{
     display: flex;
     overflow: hidden;
     margin-right: 17px;
     text-align: center;
 }

 app-index-side{
     margin-bottom: 17px;
     overflow: hidden;
 }


 .table-body{
     display: flex;
 }

 .table-rows{
    display: table;
    width: 100%;
    background-color: white;
    border-collapse: collapse;
 }
 .table-row{
     display: table-row;
     border-bottom: 1px solid;
 } 
 .table-row:last-child{
     border-bottom: 0;
 }
 .table-cell{
     min-width: 80px;
     max-width: 120px;
     display: table-cell;
     overflow-wrap: break-word;
     padding: 2px;
     border-right: 1px solid; 
  }
 .table-cell:last-child{
     border-right: 0;
  }
  .scroll{
     overflow: scroll;
  }

表组件

import {
    AfterContentChecked,
    Component, ElementRef,
    HostListener,
    Input,
    OnInit, ViewChild,
 } from '@angular/core';
 import {IndexSideComponent} from './index-side/index-side.component';
 import {IndexHeaderComponent} from './index-header/index-header.component';

 @Component({
     selector: 'app-data-table',
     templateUrl: './data-table.component.html',
     styleUrls: ['./data-table.component.css']
 })
 export class DataTableComponent implements OnInit, AfterContentChecked{

    @Input()
    selectAble: boolean; 

    @Input()
    tablehead  = 'Head';

    @Input()
    rows: string[][];

    @ViewChild(IndexSideComponent, {read: ElementRef})
    indexSide;

    @ViewChild(IndexHeaderComponent, {read: ElementRef})
    indexHeader;

    @ViewChild('scroll')
    scroll;

    headerCellWidth = [];
    sideCellHeight = [];

    @HostListener('window:resize') onWindowResize() {
       // TODO calculate new index-size
    }


    constructor(private elRef: ElementRef) {}

    ngOnInit() {

    }

    ngAfterContentChecked() {
        this.headerCellWidth = this.generateHeaderCellWidth();
        this.sideCellHeight = this.generateSideCellHeight();
        this.cellPadding();
    }

    onScroll(event) {
        this.indexHeader.nativeElement.scrollLeft =   this.scroll.nativeElement.scrollLeft;
        this.indexSide.nativeElement.scrollTop = this.scroll.nativeElement.scrollTop;
    }

    generateHeaderCellWidth() {
        const ret = [];
        const rows = this.elRef.nativeElement.getElementsByClassName('table-row');

        if (rows.length === 0) {
            return [];
        }
        for (const cell of rows[0].children) {
            ret.push(cell.getBoundingClientRect().width);
        }
        return ret;
  }

  generateSideCellHeight() {
     const ret = [];
     const rows = this.elRef.nativeElement.getElementsByClassName('table-row');
     if (rows.length === 0) {
         return ret;
     }
     for (const row of rows) {
         ret.push(row.getBoundingClientRect().height);
     }
     return ret;
 }
 generateIndexHeadNumbers() {
     const ret = [];
     if (this.rows.length === 0) {
         return ret;
     }
     for (let i = 0; i < this.rows[0].length; i++) {
         ret.push(i);
     }
     return ret;
  }
  generateIndexSideNumbers() {
       const ret = [];
       for ( let i = 0; i < this.rows.length; i++ ) {
            ret.push(i);
       }
       return ret;
  }
  cellPadding () {
      let maxRowCellCount = 0;

      for (const row of this.rows) {
          if (row.length > maxRowCellCount) {
             maxRowCellCount = row.length;
          }
      }
      for (const row of this.rows) {
          while (row.length < maxRowCellCount){
              row.push('');
          }
      }
  }
  getHeaderMargin() {
     return new Number(this.indexSide.nativeElement.getBoundingClientRect().width);
  }


}

也许我应该使用javascript动态计算表行的高度?

1 个答案:

答案 0 :(得分:0)

我认为您的课程max-height: 200px;的{​​{1}}不会增加任何东西。相反,由于您选择以这种方式分离组件。您应该将.table-container类更改为:

.scroll

对于.scroll{ height: 100%; width: 100%; overflow: scroll; max-height: 200px; // <-- Added value } ,您还应将其元数据更改为:

IndexSideComponent

然后将类@Component({ selector: 'app-index-side', template: `<div class="index-side-cell" *ngFor="let n of numbers; let i = index;" [style.height.px]="cellHeight[i]"> {{n}} </div>`, styleUrls: ['./index-side.component.css'], host: { class:'max-height' }, encapsulation: ViewEncapsulation.None }) 添加到max-height如下:

index-side.component.css

PS :侧面索引和表格单元之间会有一些不一致,这是由于整个过程( 将索引与数据分开并选择css中的像素 ),因此,如果您使用它,它会更好:

.max-height {
  max-height: 200px;
}

我曾在Chrome浏览器70.0.3538.102版上尝试过此操作。