【问题标题】:When to call function that calculates width of elements?何时调用计算元素宽度的函数?
【发布时间】:2018-05-24 05:52:47
【问题描述】:

在我的 Angular 项目中,我有两张桌子。 其中一个表加载了来自服务的数据,并在 ngOnInit 上返回此数据。

我正在计算标题列的宽度并将其应用于另一个表。 我调用 this.resizeColumn() 函数:

  ngAfterViewInit() {
this.resizeColumns();    
 }

还有:

 @HostListener('window:resize')
 onResize() {   
this.resizeColumns();
}

问题是,第一次打开页面时,计算的宽度尚未应用。 一旦我调整窗口大小,两个标题就会匹配。 这个想法是每当表格宽度发生变化时,这个函数也会被调用。 在什么事件或生命周期挂钩之后我应该调用 resizeColumn,以便最初两个表具有相同的列宽?

【问题讨论】:

  • 虽然对我来说似乎并不完全重复,但请查看这个问题和接受答案的 cmets stackoverflow.com/questions/47729202/…
  • 谢谢。我确实读过它,只是尝试了与接受的答案中相同的代码。但这并不能解决我的问题。因为只要我调整窗口大小,表头就会获取值。我一直在尝试实现这样的东西:link 但正如你所见,小提琴没有这个问题,因为它有 JS。我不知道如何在角度上做同样的事情,以便程序运行后,它会占用这些宽度。
  • 在这种情况下,让我们尝试找出问题所在。因此,当您在代码中打开页面时,宽度是否已经正确计算但没有应用它们,或者在您调整大小之前它们不可用?
  • 非常感谢!宽度在那里,但问题是:当我刷新页面(或第一次打开)时,表格首先是空的,然后被填满。因此,标题获取表格开始时的宽度。现在,在表格被填满后,源列的宽度明显发生了变化。但是在我调整窗口大小之前,这些更改不会应用于目标标题。有没有办法在调整表格大小以调用函数时收听?这样每当原始表格改变宽度时,就会调用计算函数?

标签: angular angular5


【解决方案1】:

您可以利用属性绑定来链接两个表的列宽,如this plunker 所示。在我的示例中,顶部表格中的列宽定期增加,底部表格列宽跟随属性绑定。

<table>
  <tr #table1Row>
    <td>Column 1</td>
    <td>Column 2</td>
    <td>Column 3</td>
  <tr>
</table>

<table>
  <tr>
    <td [style.width.px]="getColWidth(table1Row, 0)">Column 1</td>
    <td [style.width.px]="getColWidth(table1Row, 1)">Column 2</td>
    <td [style.width.px]="getColWidth(table1Row, 2)">Column 3</td>
  <tr>
</table>
// Get the column width from Table 1
public getColWidth(row: HTMLTableRowElement, index: number): number {
  return row.cells[index].offsetWidth;
}


更新:

如果您需要进行异步更改(以避免 Angular 异常),您可以尝试以下代码(在 this plunker 中实现)。它调用setTimeout获取当前执行周期后的新宽度。

private colWidths: Array<number> = [ 0, 0, 0 ];

public getColWidth(row: HTMLTableRowElement, index: number): number {
  let width = row.cells[index].offsetWidth;
  if (Math.abs(this.colWidths[index] - width) > 0.001) {
    setTimeout(() => {
      this.colWidths[index] = width;
    }, 0);
  }
  return this.colWidths[index];
}

【讨论】:

  • 但是我正在使用属性绑定更改列的宽度。问题是原始列标题根据内容获取其宽度。当您第一次启动应用程序时,表格一瞬间没有数据(目标列获取原始列的列宽)然后表格获取数据,原始列的宽度扩大。目标列保持不变。我想了解的是如何让目标列在原始表列发生变化时改变它们的宽度。我也在使用@ViewChildren 来获取原生元素
  • 我之前将我的函数更改为:link 而且我不确定如何更改表格以触发计算并获取宽度。
  • 在我的示例中,表 2 中的宽度与表 1 中的实际宽度相关联(使用offsetWidth 测量)。如果表 1 中的宽度发生变化以适应其内容,则表 2 中的宽度将在属性绑定的帮助下跟随。我调整了my Plunker 以在表 1 中显示内容更改的结果。请注意,使用此属性绑定,您不需要监视事件,也不必知道第一个宽度的时间表变化。 Angular 变化检测机制会为您解决这个问题。
  • 非常感谢!!!!但我很难理解:所以你使用 getColWidth(index:number) 来获取表格列的宽度?然后使用属性绑定将其绑定到表中的列? this.row.cells[index].offsetWidth,这条线怎么知道要取什么宽度?还是this.row,get row() 返回的行?所以我需要做的是使用 ViewChildren 获取行,并且我将它们的宽度设置为 offsetWidth?抱歉,我只是想确保我理解清楚。
  • 我通过将表引用变量直接传递给模板标记中的getColWidth() 简化了我的答案和my plunker。注意:模板引用变量table1Row 在plunker 的代码中也与@ViewChild() 一起使用,但只是为了增加示例中的列大小。你不需要在你的代码中这样做。
猜你喜欢
  • 2016-08-16
  • 2015-12-16
  • 1970-01-01
  • 1970-01-01
  • 2015-11-14
  • 2010-11-04
  • 1970-01-01
  • 2021-07-05
  • 1970-01-01
相关资源
最近更新 更多