Angular 19.2.0 引入了 untagged template literals in expressions 新功能,其中可以在模板的 Angular expression 中使用反引号 (backticks) 插入变数。 目的是促进元件模板内的字串串联。 支持这些案例:
- 单次插值 (Single interpolation)
- 多次插值 (Multiple interpolations)
- 用 Angular pipe 插值 (Interpolation with pipe)
此功能在 19.2.0-next 版本中出现。这不是一个稳定的版本;请使用 Stackblitz 进行测试。
ng update @angular/cli --next
ng update @angular/core --next
单次插值 (Single Interpolation)
@Component({
selector: \'app-root\',
templateUrl: `./main.component.html`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class App {
description = `${VERSION.full} - Untagged Template Literals`;
}
// main.component.html
<h1>Version {{ description }}</h1>
在 untagged template literals 功能之前,"Version" 静态文字位于 Angular Expression 之前。
// main.component.html
<h1>{{ `Version ${description}` }}</h1>
在使用 untagged template literals 功能之后,"Version" 和 description 将连接成一个字串。 h1 元素渲染 "Version 19.2.0-next.0 - Untagged Template Literals"。
多次插值 (Multiple interpolations)
@Component({
selector: \'app-root\',
templateUrl: `./main.component.html`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class App {
description = `${VERSION.full} - Untagged Template Literals`;
userName = signal(\'N/A\');
userType = signal<"user" | "admin" | "intruder">(\'user\');
componentType = computed(() => configs[this.userType()]);
inputs = computed(() => ({
permissions: this.componentType().permissions,
name: this.userName(),
type: this.userType(),
}));
}
@let ct = componentType();
<ng-container [ngComponentOutlet]="ct.type"
[ngComponentOutletInputs]="inputs()"
#instance="ngComponentOutlet"
/>
@let permissions = componentInstance?.permissions() ?? [];
@let strPermission = permissions.join(\', \');
@let numPermissions = permissions.length;
@let permissionUnit = numPermissions > 1 ? \'permissions\' : \'permission\';
@let delimiter = numPermissions >= 1 ? \', \' : \'\';
Multiple Interpolations: {{ numPermissions }} {{ permissionUnit }}{{ delimiter}}{{strPermission} }}
componentInstance 变数是动态渲染的元件。 permission 变数储存渲染元件的权限数组。 strPermission 变数将权限数组连接成一个字串。 当使用者拥有多个权限时,permissionUnit 的值为"permissions"。 当使用者有0或1个权限时,值为 "permission"。 当使用者拥有多个权限时,在权限字串前插入逗号。
在 untagged template literals 功能之前,静态文字 "Multiple Interpolations" 位于 Angular Expression 之前。 所有 expressions, numPermissions, permissionUnit, delimiter 和 strPermission 均单独插值。
// main.component.html
@let permissions = componentInstance?.permissions() ?? [];
@let strPermission = permissions.join(\', \');
@let numPermissions = permissions.length;
@let permissionUnit = numPermissions > 1 ? \'permissions\' : \'permission\';
@let delimiter = numPermissions >= 1 ? \', \' : \'\';
{{ `Multiple Interpolations: ${numPermissions} ${permissionUnit}${delimiter}${strPermission}` }}
在 untagged template literal 之后,这些变数被连接并插入到 Angular Expression 的大括号之间。
- 当使用者类型为 "Admin" 时,范本字串被评估为 "Multiple Interpolations: 4 permissions, create, edit, view, delete"。
- 当使用者类型为 "User" 时,范本字串的计算结果为 "Multiple Interpolations: 1 permission, view"。
- 当使用者类型为 "Intruder" 时,范本字串的计算结果为 "Multiple Interpolitions: 0 permission"。
用 Angular pipe 插值 (Interpolation with pipe)
@Component({
selector: \'app-admin\',
templateUrl: `app-user.component.html`,
imports: [TitleCasePipe],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AdminComponent implements Permission {
permissions = input.required<string[]>();
name = input(\'N/A\');
type = input.required<string>();
}
AdminComponent 元件导入 TitleCasePipe 管道以将 permission 和 type 输入大写。
<!-- Template string with pipe -->
<h2>{{ type() | titlecase }} Component</h2>
在 untagged template literals 之前,expression 会将 type 的讯号值传递到 titleCase 管道 (pipe)。然后,"Component" 跟在 expression 后面,前面有一个空格。
<!-- Template string with pipe -->
<h2>{{ `${type() | titlecase} Component` }}</h2>
在 untagged template literals 之后, type 讯号值传递到 titleCase 管道 (pipe),并与 "Component" 连接以在 Angular Expression 内形成一个新字串。
- 当 type 为 Admin 时,范本字串将被评估为 "Admin Component"。
- 当 type 为 User 时,范本字串被评估为 "User Component"。
- 当 type 为 Intruder 时,范本字串将被评估为「Intruder Component"。
untagged template literals 功能是将多个字串连接成一个字串并在 Angular Expression 中对其插值的便捷方法。
参考:
- PR: https://github.com/angular/angular/pull/59230
- Stackblitz Demo:
- Post by Amos Isaila: https://www.linkedin.com/feed/update/urn:li:activity:7288814996073992192/