カテゴリー
【Angular基礎講座】動的/静的ウェブサイト内のページネイション作成 〜 パスパラメータ/クエリパラメータ付きのURLアドレスからルーティングする
※ 当ページには【広告/PR】を含む場合があります。
2020/09/29
2022/08/10
/home/hoge/piyo
/home?param1=hoge¶m2=piyo
TL;DR
ActivatedRoute
queryParams
// `/home?param1=hoge¶m2=piyo`にアクセスしたときのparam1とparam2を取得
constructor(private route: ActivatedRoute) {
const param1: string = this.route.snapshot.queryParamMap.get('param1'); // hoge
const param2: string = this.route.snapshot.queryParamMap.get('param2'); // piyo
}
index.html
:
ActivatedRoute
snapshot
params
// `/home/:param1/:param2`とパスパラメータを定義して、
// 例えば/home/hoge/piyoを取得
constructor(private route: ActivatedRoute) {
const param1: string = this.route.snapshot.paramMap.get('param1'); // hoge
const param2: string = this.route.snapshot.paramMap.get('param2'); // piyo
}
動的なサイトのページング処理
/home
app-routingモジュール
app-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
const routes: Routes = [
{ path: 'error', component: PageNotFoundComponent },
{ path: 'home', component: HomeComponent },
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: '**', redirectTo: '/error', pathMatch: 'full' }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
動的なサイトのページング処理
/home
/home?page=1
/home?page=2
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-root',
template: `
<div>
<ul>
<ng-container *ngFor="let article of articleList | slice:startPos:startPos+listLength">
<li>
<a href="{{article.url}}">{{article.title}}</a>
<p>{{article.subtitle}}</p>
</li>
</ng-container>
</ul>
<ng-container *ngIf="articleList.length === 0">
<div>
<p>このカテゴリーにはまだ記事が有りません。</p>
</div>
</ng-container>
</div>
`,
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
startPos: number = 0; // リストの最初の要素番号
listLength: number = 10; // リストへの最大表示数
articleList: any[] = [
{
url: '/blog/1',
title: 'Hogeの日記',
subtitle: '今日はお肉の日でした。',
},
{
url: '/blog/2',
title: 'Piyoの日記',
subtitle: '今日はおさかなの日でした。',
},
//...中略
];
constructor(
private route: ActivatedRoute
) { }
ngOnInit() {
// リスト表示に必要なページ数の更新
const totalPages: number = Math.floor(this.articleList.length / this.listLength) + 1;
// リクエストされたルートのクエリパラメータを取得
let pageId: number = parseInt(this.route.snapshot.queryParamMap.get('page'), 10); // 1,2,3...
if (!pageId || pageId <= 0) {
// 1より小さい値はとらない
pageId = 1;
} else if (pageId <= totalPages) {
// そのページの描画開始位置を算出
this.startPos = this.listLength * (pageId - 1);
} else {
// 最大のページ数を越えないようにする
this.startPos = this.listLength * (totalPages - 1);
}
}
}
ngFor
slice
slice
this.route.snapshot.queryParamMap.get('page')
page=*
constructor
ngOnInit
クエリパラメータを用いたページの遷移
// /home?page=1
this.router.navigate(
['/home'],
{
queryParams: {
page: 1
}
}
);
routerLink
<!-- /home?page=1 -->
<a [routerLink]="['/home']" [queryParams]="{ page: 1 }"></a>
静的なサイトのページング処理
index.html
index.html
/home
/home/index.html
/home/1
/home/1/index.html
app-routingモジュールの修正
:
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
const routes: Routes = [
{ path: 'error', component: PageNotFoundComponent },
{ path: 'home', component: HomeComponent },
{ path: 'home/:page', component: HomeComponent }, // 👈追加
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: '**', redirectTo: '/error', pathMatch: 'full' }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
home/
page
サーバーサイドレンダリング(SSR)
1. ビルド時のコマンドのオプション--routesに指定のパスパラメータを追加する
2. angular.jsonのprerenderのroutesフィールドにパスパラメータを追加する
3. ビルドコマンドのオプション--routesFileを使って、
dynamic-routes.txtを指定し、このテキストにパスを追加する
4. angular.jsonのprerenderのroutesFileフィールドに、
dynamic-routes.txtのパスを追加し、ビルド時に読み込ませる
angular-prerender
--parameter-values
index.html
:page
$ npx angular-prerender --parameter-values '{":page":["1","2","3","4","5","6"]}'
/home/1
/home/2
/home/3
/home/4
/home/5
/home/6
:page
静的なサイトのページング処理
HomeComponent
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-root',
template: `
<div>
<ul>
<ng-container *ngFor="let article of articleList | slice:startPos:startPos+listLength">
<li>
<a href="{{article.url}}">{{article.title}}</a>
<p>{{article.subtitle}}</p>
</li>
</ng-container>
</ul>
<ng-container *ngIf="articleList.length === 0">
<div>
<p>このカテゴリーにはまだ記事が有りません。</p>
</div>
</ng-container>
</div>
`,
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
startPos: number = 0; // リストの最初の要素番号
listLength: number = 10; // リストへの最大表示数
articleList: any[] = [
{
url: '/blog/1',
title: 'Hogeの日記',
subtitle: '今日はお肉の日でした。',
},
{
url: '/blog/2',
title: 'Piyoの日記',
subtitle: '今日はおさかなの日でした。',
},
//...中略
];
constructor(
private route: ActivatedRoute
) { }
ngOnInit() {
// リスト表示に必要なページ数の更新
const totalPages: number = Math.floor(this.articleList.length / this.listLength) + 1;
// リクエストされたルートのパスパラメータを取得
let pageId: number = parseInt(this.route.snapshot.paramMap.get('page'), 10); // 1,2,3...
if (!pageId || pageId <= 0) {
// 1より小さい値はとらない
pageId = 1;
} else if (pageId <= totalPages) {
// そのページの描画開始位置を算出
this.startPos = this.listLength * (pageId - 1);
} else {
// 最大のページ数を越えないようにする
this.startPos = this.listLength * (totalPages - 1);
}
}
}
this.route.snapshot.paramMap
まとめ
参考サイト
記事を書いた人
ナンデモ系エンジニア
主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。
カテゴリー