*ngFor使我的应用程序非常慢,因为迭代了数千行。除了性能较慢外,它的工作与预期一样。如果选择值或输入值被更改,其值将显示为红色。如果_main。滚动是迭代的,我可以获取所有修改的值,并将它们发送给API进行更新。
<tr *ngFor="let student of _main.students"> <!-- up to 250 students (rows). -->
<ng-container *ngFor="let date of _main.attendance_dates"> <!-- up to 5 school days (rows) in the same week. -->
<ng-container *ngFor="let roll of _main.rolls"> <!-- up to 5 days (rows) times 250 students per two columns (5*250*2) in the same week. -->
<ng-container *ngIf="student.id == roll.student_id && date.date == roll.date">
<td [ngClass] = "roll.email_sent_datetime?'table-cell-attendance-code-emailed' : 'table-cell-attendance-code'">
<select [(ngModel)]="roll.attendance_type_seq_new" [ngClass]="roll.attendance_type_seq == roll.attendance_type_seq_new ? 'select-attendance-type' : 'select-attendance-type-changed'">
<option [value]="0" >Not selected</option>
<option *ngFor="let answer of _main.attendance_tyes" [value]="answer.seq">
{{answer.description}}
</option>
</select>
</td>
<td [ngClass] = "roll.email_sent_datetime?'table-cell-attendance-note-emailed' : 'table-cell-attendance-note'">
<input [(ngModel)]="roll.attendance_note_new" placeholder="" title="{{roll.attendance_note_new}}" [ngClass]="roll.attendance_note == roll.attendance_note_new ? 'input-attendance-note' : 'input-attendance-note-changed'"/>
</td>
</ng-container>
</ng-container>
</ng-container>
</tr>
*我做了一些改变。首先查找索引并显示该项。它足够快,但不会存储更改。我只能通过_main修改一个项目。卷数组。并不是对所有值都触发detectChages()。还有另一个问题。如果选择或输入的值被改变,该值仍以黑色显示,而不是红色。
<tr *ngFor="let student of _main.students"> <!-- up to 250 students (rows). -->
<ng-container *ngFor="let date of _main.attendance_dates"> <!-- up to 5 school days (rows) in the same week. -->
{{getRollSelectedIndex(student.id, date.date)}} <!-- fetch the index of the row in the rolls. -->
<!-- <ng-container *ngFor="let roll of _main.rolls"> up to 5 days (rows) times 250 students per two columns (5*250*2) in the same week. -->
<ng-container *ngIf="_index">
<td [ngClass] = "_main.rolls[_index].email_sent_datetime?'table-cell-attendance-code-emailed' : 'table-cell-attendance-code'">
<select [(ngModel)]="_main.rolls[_index].attendance_type_seq_new" [ngClass]="_main.rolls[_index].attendance_type_seq == _main.rolls[_index].attendance_type_seq_new ? 'select-attendance-type' : 'select-attendance-type-changed'">
<option [value]="0" >Not selected</option>
<option *ngFor="let answer of _main.attendance_tyes" [value]="answer.seq">
{{answer.description}}
</option>
</select>
</td>
<td [ngClass] = "_main.rolls[_index].email_sent_datetime?'table-cell-attendance-note-emailed' : 'table-cell-attendance-note'">
<input [(ngModel)]="_main.rolls[_index].attendance_note_new" placeholder="" title="{{_main.rolls[_index].attendance_note_new}}" [ngClass]="_main.rolls[_index].attendance_note == _main.rolls[_index].attendance_note_new ? 'input-attendance-note' : 'input-attendance-note-changed'"/>
</td>
</ng-container>
<!-- </ng-container> -->
</ng-container>
</tr>
在。ts文件中
getRollSelectedIndex(student_id: number, date: Date){
if (this._main.rolls != null )
{
this._index = this._main.rolls.findIndex(x=>x.student_id === student_id && x.attendance_date === date)
}
}
我不是一个有经验的Angular程序员。我的方法可能是错误的,是否有更好的方法来解决代码中的性能问题?
是的,有更好的方法。您的两个解决方案都需要嵌套迭代,您可以通过在rolls
上迭代并创建一个对象来避免这种情况,其中键是学生id,值是roll。对象为您提供了即时访问,因此您不必在模板中遍历它。你可以这样做来构建这个'map':
studentRollsMap = {};
this._main.rolls.forEach(roll => {
studentRollsMap[roll.student_id] = roll;
})
然后在你的模板中,你可以迭代students
,同时能够绑定到studentRollsMap[student.id]
根据您的注释,这应该可以将性能提高5到10倍
我能感觉到你现在的紧张,我希望我的话能对你找到最好的解决办法有所帮助。
我认为作为一个好的解决方案,是在类文件中而不是在模板文件中做所有的条件反射样式类。使用.map()
迭代数据数组,并为数组中的每个对象添加两个新属性,一个用于<td>
类roll.email_sent_datetime?'table-cell-attendance-code-emailed' : 'table-cell-attendance-code'"
,另一个用于<input>
样式类_main.rolls[_index].email_sent_datetime?'table-cell-attendance-note-emailed' : 'table-cell-attendance-note'"
。
我相信使用这种方式将把调整样式所花费的时间缩短到零,并且将是可触摸的。
甚至,您可以遍历整个可靠的数据数组_main.students
、_main.attendance_dates
和_main.rolls
,以便在*ngFor=""
[也在类.ts文件中]中只使用一个数据数组