angular-routing
Angular v20以降のアプリケーションにおいて、遅延読み込み・関数型ガード・リゾルバー・ルートパラメータを活用したルーティングを実装します。ナビゲーションの設定、保護されたルート、ルートベースのデータ読み込み、ネストされたルーティングに活用できます。ルート設定、認証ガードの追加、遅延読み込みの実装、またはシグナルを使ったルートパラメータの取得を行う際にトリガーされます。
description の原文を見る
Implement routing in Angular v20+ applications with lazy loading, functional guards, resolvers, and route parameters. Use for navigation setup, protected routes, route-based data loading, and nested routing. Triggers on route configuration, adding authentication guards, implementing lazy loading, or reading route parameters with signals.
SKILL.md 本文
Angular ルーティング
Angular v20+ で遅延ロード、関数型ガード、シグナルベースのルートパラメータを使用してルーティングを設定します。
基本的なセットアップ
// app.routes.ts
import { Routes } from '@angular/router';
export const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home', component: Home },
{ path: 'about', component: About },
{ path: '**', component: NotFound },
];
// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
],
};
// app.component.ts
import { Component } from '@angular/core';
import { RouterOutlet, RouterLink, RouterLinkActive } from '@angular/router';
@Component({
selector: 'app-root',
imports: [RouterOutlet, RouterLink, RouterLinkActive],
template: `
<nav>
<a routerLink="/home" routerLinkActive="active">Home</a>
<a routerLink="/about" routerLinkActive="active">About</a>
</nav>
<router-outlet />
`,
})
export class App {}
遅延ロード
フィーチャーモジュールをオンデマンドで読み込みます:
// app.routes.ts
export const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home', component: Home },
// フィーチャー全体を遅延ロード
{
path: 'admin',
loadChildren: () => import('./admin/admin.routes').then(m => m.adminRoutes),
},
// 単一コンポーネントを遅延ロード
{
path: 'settings',
loadComponent: () => import('./settings/settings.component').then(m => m.Settings),
},
];
// admin/admin.routes.ts
export const adminRoutes: Routes = [
{ path: '', component: AdminDashboard },
{ path: 'users', component: AdminUsers },
{ path: 'settings', component: AdminSettings },
];
ルートパラメータ
シグナル入力を使用 (推奨)
// ルート設定
{ path: 'users/:id', component: UserDetail }
// コンポーネント - ルートパラメータに input() を使用
import { Component, input, computed } from '@angular/core';
@Component({
selector: 'app-user-detail',
template: `
<h1>User {{ id() }}</h1>
`,
})
export class UserDetail {
// ルートパラメータをシグナル入力として
id = input.required<string>();
// ルートパラメータに基づいた計算値
userId = computed(() => parseInt(this.id(), 10));
}
withComponentInputBinding() で有効化します:
// app.config.ts
import { provideRouter, withComponentInputBinding } from '@angular/router';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes, withComponentInputBinding()),
],
};
クエリパラメータ
// ルート: /search?q=angular&page=1
@Component({...})
export class Search {
// クエリパラメータを入力として
q = input<string>('');
page = input<string>('1');
currentPage = computed(() => parseInt(this.page(), 10));
}
ActivatedRoute を使用 (代替方法)
import { Component, inject } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { toSignal } from '@angular/core/rxjs-interop';
import { map } from 'rxjs';
@Component({...})
export class UserDetail {
private route = inject(ActivatedRoute);
// ルートパラメータをシグナルに変換
id = toSignal(
this.route.paramMap.pipe(map(params => params.get('id'))),
{ initialValue: null }
);
// クエリパラメータ
query = toSignal(
this.route.queryParamMap.pipe(map(params => params.get('q'))),
{ initialValue: '' }
);
}
関数型ガード
認証ガード
// guards/auth.guard.ts
import { inject } from '@angular/core';
import { CanActivateFn, Router } from '@angular/router';
export const authGuard: CanActivateFn = (route, state) => {
const authService = inject(Auth);
const router = inject(Router);
if (authService.isAuthenticated()) {
return true;
}
// 戻り URL 付きでログインにリダイレクト
return router.createUrlTree(['/login'], {
queryParams: { returnUrl: state.url },
});
};
// ルートでの使用
{
path: 'dashboard',
component: Dashboard,
canActivate: [authGuard],
}
ロールガード
export const roleGuard = (allowedRoles: string[]): CanActivateFn => {
return (route, state) => {
const authService = inject(Auth);
const router = inject(Router);
const userRole = authService.currentUser()?.role;
if (userRole && allowedRoles.includes(userRole)) {
return true;
}
return router.createUrlTree(['/unauthorized']);
};
};
// 使用方法
{
path: 'admin',
component: Admin,
canActivate: [authGuard, roleGuard(['admin', 'superadmin'])],
}
キャン・ディアクティベート・ガード
export interface CanDeactivate {
canDeactivate: () => boolean | Promise<boolean>;
}
export const unsavedChangesGuard: CanDeactivateFn<CanDeactivate> = (component) => {
if (component.canDeactivate()) {
return true;
}
return confirm('You have unsaved changes. Leave anyway?');
};
// コンポーネント実装
@Component({...})
export class Edit implements CanDeactivate {
form = inject(FormBuilder).group({...});
canDeactivate(): boolean {
return !this.form.dirty;
}
}
// ルート
{
path: 'edit/:id',
component: Edit,
canDeactivate: [unsavedChangesGuard],
}
リゾルバー
ルート有効化前にデータを事前取得します:
// resolvers/user.resolver.ts
import { inject } from '@angular/core';
import { ResolveFn } from '@angular/router';
export const userResolver: ResolveFn<User> = (route) => {
const userService = inject(User);
const id = route.paramMap.get('id')!;
return userService.getById(id);
};
// ルート設定
{
path: 'users/:id',
component: UserDetail,
resolve: { user: userResolver },
}
// コンポーネント - 入力経由で解決されたデータにアクセス
@Component({...})
export class UserDetail {
user = input.required<User>();
}
ネストされたルート
// 子を持つ親ルート
export const routes: Routes = [
{
path: 'products',
component: ProductsLayout,
children: [
{ path: '', component: ProductList },
{ path: ':id', component: ProductDetail },
{ path: ':id/edit', component: ProductEdit },
],
},
];
// ProductsLayout
@Component({
imports: [RouterOutlet],
template: `
<h1>Products</h1>
<router-outlet /> <!-- 子ルートはここに表示されます -->
`,
})
export class ProductsLayout {}
プログラマティック・ナビゲーション
import { Component, inject } from '@angular/core';
import { Router } from '@angular/router';
@Component({...})
export class Product {
private router = inject(Router);
// ルートにナビゲート
goToProducts() {
this.router.navigate(['/products']);
}
// パラメータ付きでナビゲート
goToProduct(id: string) {
this.router.navigate(['/products', id]);
}
// クエリパラメータ付きでナビゲート
search(query: string) {
this.router.navigate(['/search'], {
queryParams: { q: query, page: 1 },
});
}
// 現在のルートから相対的にナビゲート
goToEdit() {
this.router.navigate(['edit'], { relativeTo: this.route });
}
// 現在のヒストリーエントリを置き換え
replaceUrl() {
this.router.navigate(['/new-page'], { replaceUrl: true });
}
}
ルートデータ
// 静的ルートデータ
{
path: 'admin',
component: Admin,
data: {
title: 'Admin Dashboard',
roles: ['admin'],
},
}
// コンポーネント内でアクセス
@Component({...})
export class AdminCmpt {
title = input<string>(); // ルートデータから
roles = input<string[]>(); // ルートデータから
}
// または ActivatedRoute経由
private route = inject(ActivatedRoute);
data = toSignal(this.route.data);
ルーターイベント
import { Router, NavigationStart, NavigationEnd } from '@angular/router';
import { filter } from 'rxjs';
@Component({...})
export class AppMain {
private router = inject(Router);
isNavigating = signal(false);
constructor() {
this.router.events.pipe(
filter(e => e instanceof NavigationStart || e instanceof NavigationEnd)
).subscribe(event => {
this.isNavigating.set(event instanceof NavigationStart);
});
}
}
高度なパターンについては、references/routing-patterns.md を参照してください。
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- analogjs
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/analogjs/angular-skills / ライセンス: MIT
関連スキル
hugging-face-trackio
Trackioを使用してMLトレーニング実験を追跡・可視化できます。トレーニング中のメトリクスログ記録(Python API)、トレーニング診断のアラート発火、ログされたメトリクスの取得・分析(CLI)が必要な場合に活用してください。リアルタイムダッシュボード表示、Webhookを使用したアラート、HF Space同期、自動化向けのJSON出力に対応しています。
btc-bottom-model
ビットコインのサイクルタイミングモデルで、加重スコアリングシステムを搭載しています。日次パルス(4指標、32ポイント)とウィークリー構造(9指標、68ポイント)の2カテゴリーにわたる13の指標を追跡し、0~100のマーケットヒートスコアを算出します。ETFフロー、ファンディングレート、ロング/ショート比率、恐怖・貪欲指数、LTH-MVRV、NUPL、SOPR(LTH+STH)、LTH供給率、移動平均倍率(365日MA、200週MA)、週次RSI、出来高トレンドに対応します。市場サイクル全体を通じて買いと売りの両方の推奨を提供します。ビットコインの底値拾い、BTCサイクルポジション、買い時・売り時、オンチェーン指標、MVRV、NUPL、SOPR、LTH動向、ETFの流出入、ファンディングレート、恐怖指数、ビットコインが過熱状態か、マイナーコスト、暗号資産市場のセンチメント、BTCのポジションサイジング、「今ビットコインを買うべきか」「BTCが天井をつけているか」「オンチェーン指標は何を示しているか」といった質問の際にこのスキルを活用します。
protein_solubility_optimization
タンパク質の溶解性最適化 - タンパク質の溶解性を最適化します。タンパク質の特性を計算し、溶解性と親水性を予測し、有効な変異を提案します。タンパク質配列の特性計算、タンパク質機能の予測、親水性計算、ゼロショット配列予測を含むタンパク質エンジニアリング業務に使用できます。3つのSCPサーバーから4つのツールを統合しています。
research-lookup
Parallel Chat APIまたはPerplexity sonar-pro-searchを使用して、最新の研究情報を検索できます。学術論文の検索にも対応しています。クエリは自動的に最適なバックエンドにルーティングされるため、論文の検索、研究データの収集、科学情報の検証に活用できます。
tree-formatting
ggtree(R)またはiTOL(ウェブ)を使用して、系統樹の可視化とフォーマットを行います。系統樹を図として描画する際、ツリーレイアウトの選択、分類学に基づく枝やラベルの色付け、クレードの折りたたみ、サポート値の表示、またはツリーへのオーバーレイ追加が必要な場合に使用してください。系統推定(protein-phylogenyスキルを使用)やドメイン注釈(今後の独立したスキル)には使用しないでください。
querying-indonesian-gov-data
インドネシア政府の50以上のAPIとデータソースに接続できます。BPJPH(ハラール認証)、BOM(食品安全)、OJK(金融適正性)、BPS(統計)、BMKG(気象・地震)、インドネシア中央銀行(為替レート)、IDX(株式)、CKAN公開データポータル、pasal.id(第三者法MCP)に対応しています。インドネシア政府データを活用したアプリ開発、.go.idウェブサイトのスクレイピング、ハラール認証の確認、企業の法的適正性の検証、金融機関ステータスの照会、またはインドネシアMCPサーバーへの接続時に使用できます。CSRF処理、CKAN API使用方法、IP制限回避など、すぐに実行可能なPythonパターンを含んでいます。