在 Angular 5 上动态更改元素宽度

Change element width dynamically on Angular 5

我有两个table。

我想将一个 table 的列宽设置为等于另一个 table 的列宽。

像这样:

    <table class="table-header table">
        <thead class="table-bordered">
          <tr>
              <th>Name</th>
              <th>Last Name</th>
              <th>Gender</th>
              <th>Education</th>
            </tr>
        </thead>
      </table>

另一个table:

          <table class="table-header table">
         <thead class="table-bordered">
          <tr>
              <th>Name</th>
              <th>Last Name</th>
              <th>Gender</th>
              <th>Education</th>
            </tr>
        </thead>
      <tbody> 
         <tr> 
            <td> Ross </td>
             <td> Ross </td>
            <td> M</td>
            <td> BsC </td>
        ..
      </tbody>

我想要做的是让第一个 table 的所有 headers 始终等于第二个 table 的 headers 宽度。 因为在第二个 table 它们会根据内容调整大小。

所以我知道我可以添加一个 HostListener('window:resize') 但是如何在 Angular 中分配这些值? 所以他们总是一样的。就好像它是彼此的复制品一样。 有指导吗?

首先,您需要获取源 table 列和目标 table 列的引用,您可以使用模板变量和 @ViewChildren 装饰器来完成此操作。

在您的模板中:

<!-- Source table -->
<table class="table-header table">
  <thead class="table-bordered">
    <tr>
        <th #sourceTh>Name</th>
        <th #sourceTh>Last Name</th>
        <th #sourceTh>Gender</th>
        <th #sourceTh>Education</th>
      </tr>
  </thead>
</table>

<!-- Target table -->
<table class="table-header table">
  <thead class="table-bordered">
    <tr>
      <th #targetTh>Name</th>
      <th #targetTh>Last Name</th>
      <th #targetTh>Gender</th>
      <th #targetTh>Education</th>
    </tr>
  </thead>
  <tbody>
    <!-- table body content -->
  </tbody>
</table>

然后在你的内部组件class

@Component({ ... })  
export class MyClass {
  @ViewChildren('sourceTh')
  sourceTh: QueryList<ElementRef>;

  @ViewChildren('targetTh')
  targetTh: QueryList<ElementRef>;

  // ...
}

这样您可以获得 QueryList 个元素引用,因此您可以访问每个 table 标题(实际 DOM 节点)的 nativeElement 并获得每个人 offsetWidth。注意 @ViewChild@ViewChildren 装饰属性仅在 AfterViewInit 生命周期钩子之后可用。 QueryList 是一个 array-like 数据结构,它有一些数组方法,如 forEachmap 等...

ngAfterViewInit 中,您想遍历源列表 table header 单元格,获取每个宽度,然后遍历目标 header 单元格列表并设置宽度。为此,您可以使用 Renderer2 中的 setStyle 方法。然后你也可以在 window.resize 事件或任何

事件上调用此方法
@Component({ ... })  
export class MyClass implements AfterViewInit {
  @ViewChildren('sourceTh')
  sourceTh: QueryList<ElementRef>;

  @ViewChildren('targetTh')
  targetTh: QueryList<ElementRef>;

  constructor( private renderer: Renderer2 ) {}

  ngAfterViewInit() {
    this.resizeColumns();
  }

  resizeColumns() {
    let widths = this.sourceTh.map(th => th.nativeElement.offsetWidth);

    this.targetTh.forEach((th, index) => {
      this.renderer.setStyle(
        th.nativeElement, 
        'width', 
        `${widths[index]}px`
      );
    });
  }
}

这确实有效,但如果您按 ctrl f5,它会破坏 table。为了解决这个问题,我不得不使用 ngAfterVeiwChecked 但是当 dom 更改或屏幕尺寸更改等时,生命周期挂钩会不断触发......我不确定我能否找到有效的方法。

在图片中,如果您要执行 ctrl + f5,您会看到 headers 中断,但是之后,如果您只是简单地通过刷新按钮刷新页面,就可以了。就在你按 ctrl f5

的时候

Broken Headers