Angular 19: Немаркированные шаблонные литералы в выражениях

В версии Angular 19.2.0 появилась возможность использовать немаркированные шаблонные литералы в выражениях. Это позволяет интерполировать переменные, используя обратные кавычки, непосредственно внутри Angular-выражений в шаблонах. Главная цель нововведения – упростить конкатенацию строк в шаблонах компонентов.
Поддерживаются следующие сценарии:
- Одинарная интерполяция
- Множественная интерполяция
- Интерполяция с пайпом
Функционал доступен начиная с версии 19.2.0-next и может быть протестирован в демо-примере на Stackblitz.
ng update @angular/cli --next
ng update @angular/core --next
Одинарная интерполяция
@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>
До использования немаркированного шаблонного литерала статический текст «Version» располагается перед выражением.
// main.component.html
<h1>{{ `Version ${description}` }}</h1>
После применения функционала немаркированных шаблонных литералов статический текст «Version» и выражение description
объединяются в одну строку. Элемент h1
отображает "Version 19.2.0-next.0 - Unlabeled Template Literals".
Множественная интерполяция
@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(),
}));
}
// main.component.html
@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
содержит динамически отрисованный компонент. Переменная permissions
хранит массив разрешений отрисованного компонента. Переменная strPermission
объединяет массив permissions
в строку. Переменная permissionUnit
принимает значение «permissions», если у пользователя несколько разрешений, и «permission» – если разрешение одно или отсутствует. Запятая добавляется перед строкой разрешений, если у пользователя более одного разрешения.
Перед использованием немаркированного шаблонного литерала статический текст "Multiple Interpolations" располагается перед выражениями. Все выражения – 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}` }}
После применения немаркированных шаблонных литералов эти переменные объединяются и интерполируются внутри фигурных скобок Angular-выражения.
- Если тип пользователя – Admin, строка шаблона принимает значение «Multiple Interpolations: 4 permissions: create (создание), edit (редактирование), view (просмотр), delete (удаление)».
- Если тип пользователя – User, строка шаблона принимает значение «Multiple Interpolations: 1 permission: view».
- Если тип пользователя – Intruder, строка шаблона принимает значение «Multiple Interpolations: 0 permissions».
Интерполяция с пайпом
@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
для преобразования разрешений и типа пользователя к верхнему регистру.
Перед немаркированным шаблонным литералом значение сигнала type
передается в пайп titleCase
. Затем следует статический текст "Component" с предшествующим пробелом.
После применения немаркированных шаблонных литералов преобразованное значение сигнала объединяется со статическим текстом "Component", формируя новую строку внутри Angular-выражения.
- Если тип пользователя – Admin, строка шаблона принимает значение «Admin Component».
- Если тип пользователя – User, строка шаблона принимает значение «User Component».
- Если тип пользователя – Intruder, строка шаблона принимает значение «Intruder Component».
Функция немаркированных шаблонных литералов предоставляет удобный способ объединения строк и их вычисления внутри Angular-выражений. В зависимости от стиля кода и предпочтений команды разработчики могут использовать как немаркированные шаблонные литералы, так и ES6 шаблонные строки для конкатенации и интерполяции строк в шаблонах.