← 解説「@let — テンプレート内にローカル変数を作る」に戻る
サンプルコードで身につける: @let — テンプレート内にローカル変数を作る
解説で学んだ概念を、5つの具体例で確認します。素朴な例から実務寄りの例へと進みます。
1計算式に名前を付ける
@let のいちばん基本の形で、税込価格の計算に taxed という名前を付けています。同じ式を2回書かずに済み、元の price() が変われば @let の結果も自動で追従します。
import { Component, signal } from '@angular/core';
@Component({
selector: 'app-price-tag',
// 計算結果に taxed という名前を付けて使い回す
template:
'@let taxed = price() * 1.1;' +
'<p>税込 {{ taxed }} 円</p>' +
'<p>2個なら {{ taxed * 2 }} 円</p>',
})
export class PriceTagComponent {
price = signal(1000);
}
2深いプロパティアクセスを短くする
user()?.profile?.address?.city のような深いアクセスは、繰り返し書くとテンプレートが読みにくくなります。@let で一度だけ書いて名前を付ければ、以降は短い変数名で済み、?. の連鎖も1か所にまとまります。
import { Component, signal } from '@angular/core';
type User = { profile?: { address?: { city: string } } };
@Component({
selector: 'app-shipping-info',
// 深いアクセスを1か所にまとめ、以降は city で参照する
template:
'@let city = user()?.profile?.address?.city ?? "未設定";' +
'<p>お届け先: {{ city }}</p>' +
'<p>{{ city }}への配送は3日かかります</p>',
})
export class ShippingInfoComponent {
user = signal<User | null>({ profile: { address: { city: '札幌' } } });
}
3@for の行ごとに小計を作る
@let は @for の中でも使え、その行だけで有効なローカル変数になります。行ごとの小計のような「各要素から導く値」に名前を付けると、繰り返し部分のテンプレートがすっきりします。
import { Component, signal } from '@angular/core';
type Item = { id: number; name: string; price: number; qty: number };
@Component({
selector: 'app-cart-list',
// 行ごとに subtotal を宣言する。スコープはその繰り返しの中だけ
template:
'<ul>' +
' @for (item of items(); track item.id) {' +
' @let subtotal = item.price * item.qty;' +
' <li>{{ item.name }}: {{ subtotal }} 円</li>' +
' }' +
'</ul>',
})
export class CartListComponent {
items = signal<Item[]>([
{ id: 1, name: 'りんご', price: 150, qty: 3 },
{ id: 2, name: 'メロン', price: 1200, qty: 1 },
]);
}
4長い条件式に名前を付けて @if で使う
複数の条件を && でつないだ式は、@let で canSubmit のような意図が伝わる名前を付けてから @if や [disabled] に渡すと読みやすくなります。条件の意味が名前で説明されるので、テンプレートがそのまま仕様書のように読めます。
import { Component, signal } from '@angular/core';
@Component({
selector: 'app-submit-area',
// 条件のかたまりに「送信できるか」という名前を付ける
template:
'@let canSubmit = name().length > 0 && agreed() && !sending();' +
'<button [disabled]="!canSubmit">送信</button>' +
'@if (!canSubmit) {' +
' <p>入力と同意を済ませてください</p>' +
'}',
})
export class SubmitAreaComponent {
name = signal('');
agreed = signal(false);
sending = signal(false);
}
5@let のスコープは宣言したブロックの中だけ
@if ブロックの中で宣言した @let は、そのブロックの外からは参照できません。外でも使いたい変数はテンプレートの先頭側(ブロックの外)で宣言する、というスコープの感覚はJavaScriptの let と同じです。
import { Component, signal } from '@angular/core';
@Component({
selector: 'app-scope-demo',
// total は外で宣言したのでどこでも使える。
// discounted は @if の中で宣言したので中でしか使えない
template:
'@let total = price() * qty();' +
'<p>合計 {{ total }} 円</p>' +
'@if (total >= 5000) {' +
' @let discounted = total * 0.9;' +
' <p>1割引で {{ discounted }} 円!</p>' +
'}' +
'<!-- ここで {{ discounted }} と書くとコンパイルエラー -->',
})
export class ScopeDemoComponent {
price = signal(1200);
qty = signal(5);
}