mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
fix(migrations): handle templates outside of component in cf migration (#53368)
If a template is passed in as an input, the ng-template will not exist in the same component template. This will leave a template placeholder behind. This fix ensures that template placeholder gets turned into a template outlet. fixes: #53361 PR Close #53368
This commit is contained in:
parent
5a0ed28c9d
commit
01b18a4248
2 changed files with 52 additions and 0 deletions
|
|
@ -355,12 +355,30 @@ export function processNgTemplates(template: string): {migrated: string, err: Er
|
|||
updateTemplates(template, templates);
|
||||
}
|
||||
}
|
||||
// template placeholders may still exist if the ng-template name is not
|
||||
// present in the component. This could be because it's passed in from
|
||||
// another component. In that case, we need to replace any remaining
|
||||
// template placeholders with template outlets.
|
||||
template = replaceRemainingPlaceholders(template);
|
||||
return {migrated: template, err: undefined};
|
||||
} catch (err) {
|
||||
return {migrated: template, err: err as Error};
|
||||
}
|
||||
}
|
||||
|
||||
function replaceRemainingPlaceholders(template: string): string {
|
||||
const replaceRegex = new RegExp(`#\\w*\\|`, 'g');
|
||||
const placeholders = [...template.matchAll(replaceRegex)];
|
||||
let migrated = template;
|
||||
for (let ph of placeholders) {
|
||||
const placeholder = ph[0];
|
||||
const name = placeholder.slice(1, placeholder.length - 1);
|
||||
migrated =
|
||||
template.replace(placeholder, `<ng-template [ngTemplateOutlet]="${name}"></ng-template>`);
|
||||
}
|
||||
return migrated;
|
||||
}
|
||||
|
||||
/**
|
||||
* determines if the CommonModule can be safely removed from imports
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -4012,6 +4012,40 @@ describe('control flow migration', () => {
|
|||
`}\n`,
|
||||
].join('\n'));
|
||||
});
|
||||
|
||||
it('should add an ngTemplateOutlet when the template placeholder does not match a template',
|
||||
async () => {
|
||||
writeFile('/comp.ts', `
|
||||
import {Component} from '@angular/core';
|
||||
import {NgIf} from '@angular/common';
|
||||
|
||||
@Component({
|
||||
templateUrl: './comp.html'
|
||||
})
|
||||
class Comp {
|
||||
show = false;
|
||||
}
|
||||
`);
|
||||
|
||||
writeFile('/comp.html', [
|
||||
`<button *ngIf="active; else defaultTemplate">`,
|
||||
` Hello!`,
|
||||
`</button>`,
|
||||
].join('\n'));
|
||||
|
||||
await runMigration();
|
||||
const content = tree.readContent('/comp.html');
|
||||
|
||||
expect(content).toBe([
|
||||
`@if (active) {`,
|
||||
` <button>`,
|
||||
` Hello!`,
|
||||
` </button>`,
|
||||
`} @else {`,
|
||||
` <ng-template [ngTemplateOutlet]="defaultTemplate"></ng-template>`,
|
||||
`}`,
|
||||
].join('\n'));
|
||||
});
|
||||
});
|
||||
|
||||
describe('formatting', () => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue