Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(compiler): correctly intercept index in loop tracking function (#…
…53604) The for loop tracking function doesn't allow references to local template variables, aside from `$index` and the item which are passed in as parameters. We enforce this by rewriting all variable references to the components scope. The problem is that the logic that rewrites the references first walks the view tree and then checks if the variable is `$index` or the item. This is problematic in nested for loops, because it'll find the `$index` of the parent. These changes resolve the issue by checking for `$index` and the item first. Fixes #53600. PR Close #53604
- Loading branch information
1 parent
513fee8
commit de5c9ca
Showing
5 changed files
with
137 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
.../test/compliance/test_cases/r3_view_compiler_control_flow/nested_for_tracking_function.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import {Component} from '@angular/core'; | ||
|
||
@Component({ | ||
template: ` | ||
@for (grandparent of items; track trackByGrandparent(grandparent, $index)) { | ||
@for (parent of grandparent.items; track trackByParent(parent, $index)) { | ||
@for (child of parent.items; track trackByChild(child, $index)) { | ||
} | ||
} | ||
} | ||
`, | ||
}) | ||
export class MyApp { | ||
items: any[] = []; | ||
trackByGrandparent = (item: any, index: number) => index; | ||
trackByParent = (item: any, index: number) => index; | ||
trackByChild = (item: any, index: number) => index; | ||
} |
44 changes: 44 additions & 0 deletions
44
...pliance/test_cases/r3_view_compiler_control_flow/nested_for_tracking_function_template.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
function _forTrack0($index, $item) { | ||
return this.trackByGrandparent($item, $index); | ||
} | ||
|
||
function _forTrack1($index, $item) { | ||
return this.trackByParent($item, $index); | ||
} | ||
|
||
function _forTrack2($index, $item) { | ||
return this.trackByChild($item, $index); | ||
} | ||
|
||
function MyApp_For_1_For_1_For_1_Template(rf, ctx) {} | ||
|
||
function MyApp_For_1_For_1_Template(rf, ctx) { | ||
if (rf & 1) { | ||
$r3$.ɵɵrepeaterCreate(0, MyApp_For_1_For_1_For_1_Template, 0, 0, null, null, _forTrack2, true); | ||
} | ||
if (rf & 2) { | ||
const $parent_r7$ = ctx.$implicit; | ||
$r3$.ɵɵrepeater($parent_r7$.items); | ||
} | ||
} | ||
|
||
function MyApp_For_1_Template(rf, ctx) { | ||
if (rf & 1) { | ||
$r3$.ɵɵrepeaterCreate(0, MyApp_For_1_For_1_Template, 2, 0, null, null, _forTrack1, true); | ||
} | ||
if (rf & 2) { | ||
const $grandparent_r1$ = ctx.$implicit; | ||
$r3$.ɵɵrepeater($grandparent_r1$.items); | ||
} | ||
} | ||
|
||
… | ||
|
||
function MyApp_Template(rf, ctx) { | ||
if (rf & 1) { | ||
$r3$.ɵɵrepeaterCreate(0, MyApp_For_1_Template, 2, 0, null, null, _forTrack0, true); | ||
} | ||
if (rf & 2) { | ||
$r3$.ɵɵrepeater(ctx.items); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters