fix(core): handle for alias with as in control flow migration (#52183)

This adds the support of `let index as myIndex` in `*ngFor` for the control flow migration.

Before: `@for (itm of items; track itm)`
After: `@for (itm of items; track itm; let myIndex = $index)`

PR Close #52183
This commit is contained in:
cexbrayat 2023-10-12 15:15:44 +02:00 committed by Pawel Kozlowski
parent 1c4a3677eb
commit 37c8fd79ac
2 changed files with 38 additions and 2 deletions

View file

@ -169,7 +169,8 @@ export function migrateTemplate(template: string): string|null {
function migrateNgFor(
etm: ElementToMigrate, tmpl: string, offset: number): {tmpl: string, offset: number} {
const aliasRegexp = /=\s+(count|index|first|last|even|odd)/gm;
const aliasWithEqualRegexp = /=\s+(count|index|first|last|even|odd)/gm;
const aliasWithAsRegexp = /(count|index|first|last|even|odd)\s+as/gm;
const aliases = [];
const parts = etm.attr.value.split(';');
@ -187,10 +188,20 @@ function migrateNgFor(
trackBy = `${trackByFn}($index, ${loopVar})`;
}
// aliases
if (part.match(aliasRegexp)) {
// declared with `let myIndex = index`
if (part.match(aliasWithEqualRegexp)) {
// 'let myIndex = index' -> ['let myIndex', 'index']
const aliasParts = part.split('=');
// -> 'let myIndex = $index'
aliases.push(` ${aliasParts[0].trim()} = $${aliasParts[1].trim()}`);
}
// declared with `index as myIndex`
if (part.match(aliasWithAsRegexp)) {
// 'index as myIndex' -> ['index', 'myIndex']
const aliasParts = part.split(/\s+as\s+/);
// -> 'let myIndex = $index'
aliases.push(` let ${aliasParts[1].trim()} = $${aliasParts[0].trim()}`);
}
}
const aliasStr = (aliases.length > 0) ? `;${aliases.join(';')}` : '';

View file

@ -521,6 +521,31 @@ describe('control flow migration', () => {
'template: `<ul>@for (itm of items; track itm; let index = $index) {<li>{{itm.text}}</li>}</ul>`');
});
it('should migrate with alias declared with as', async () => {
writeFile('/comp.ts', `
import {Component} from '@angular/core';
import {NgFor} from '@angular/common';
interface Item {
id: number;
text: string;
}
@Component({
imports: [NgFor],
template: \`<ul><li *ngFor="let itm of items; index as myIndex">{{itm.text}}</li></ul>\`
})
class Comp {
items: Item[] = [{id: 1, text: 'blah'},{id: 2, text: 'stuff'}];
}
`);
await runMigration();
const content = tree.readContent('/comp.ts');
expect(content).toContain(
'template: `<ul>@for (itm of items; track itm; let myIndex = $index) {<li>{{itm.text}}</li>}</ul>`');
});
it('should migrate with multiple aliases', async () => {
writeFile('/comp.ts', `
import {Component} from '@angular/core';