javascript - 父组件的角度无限重新渲染
问题描述
您好,我的 Angular7 应用程序由一个名为 的父组件timesheet
和一个名为 的子组件组成row
。在这个例子中,我想timesheet
生成一个<app-row>
为给定月份的每一天
现在,<app-row>
组件只包含一个带有接受数字的字段的<td>
元素。input
到目前为止没有什么太花哨的。
时间表组件:
<div *ngFor="let week of splitMonthIntoWeeks(getMonthDays(month))">
<table>
<thead>
<tr>
<th>
Hours:
</th>
</tr>
</thead>
<tbody>
<tr app-row *ngFor="let day of week"></tr>
</tbody>
</table>
</div>
行组件:
<td><input type="number"></td>
这工作得很好。但是,如果我尝试使用[(ngModel)]
指令将每个行组件的输入元素链接到模型中的属性,我会无限次重新呈现应用程序(您可以在上面的链接中重现。起初它会正常工作,你必须添加[(ngModel)]
指令添加到行组件,如下所示)。
总而言之,这种变化提供了无限的重新渲染:
<td><input type="number" [(ngModel)]="hours"></td>
现在,我真的不知道 Angular 如何管理更改,也许我遗漏了一些东西,所以任何提示都将不胜感激。
解决方案
在此处查看解决方案
https://stackblitz.com/edit/angular-cjxqyt
你不应该直接在模板中调用你的函数(splitMonthIntoWeeks
和getMonthDays
),因为它会在每个渲染周期被调用。Date
这意味着对于每次调用,都会生成一个包含 new 的新数组。ngFor
通过检查其值是否与===
上一个循环严格相同的对象(带有 )来工作。
如果比较不匹配,ngFor
则认为它是一个新对象,因此它会销毁相应的 DOM 元素并生成一个新对象。您可以console.log
在RowComponent
组件构造函数中看到它。
在比较两个复杂对象时,就像Date
它检查对象是否真的相同(内存中的指针相同),但在您的情况下,这不是因为函数不断重新创建新对象。
因此,您可以创建数组并将结果保存在本地属性中,并仅在@Input
month
更改时重新计算此数组,而不是在每个周期中调用您的函数。为此,您可以使用onChanges
生命周期,或为您使用 setter @Input
(如我的示例中)。
推荐阅读
- javascript - 动画边框颜色
- php - PHP如果变量等于下拉列表中的值,则将“选定”属性添加到选项
- linux - crontab 不执行 python 脚本
- javascript - 如何使用 React 访问 JSON 格式中包含的对象数组中的特定元素?
- javascript - 如何将变量传递给 i18n
- asp.net - Angular / Asp.Net Web Api 请求二进制数据
- java - 当您不知道属性名称时如何使用 Jackson Serializer
- liquibase - Liquibase generateChangeLog 命令生成无变更集
- javascript - 如何在 Javascript 中将 ArrayBuffer 转换为 11 位值并再次返回
- go - 如何在 Go 中获取包含数据结构的结构的大小?