Browse Source

查詢字串的傳遞與取得=> page使用

可以往前往後,使用queryParamsHandling: 'preserve'來紀錄先前的資料
HarveyChou 2 years ago
parent
commit
32b24fb072
  1. 4
      src/app/app.component.html
  2. 1
      src/app/task-form-page/task-form-page.component.html
  3. 26
      src/app/task-form-page/task-form-page.component.ts
  4. 4
      src/app/task-page/task-page.component.html
  5. 51
      src/app/task-page/task-page.component.ts
  6. 27
      src/app/task.service.ts
  7. 24
      src/assets/tasks.json

4
src/app/app.component.html

@ -5,7 +5,9 @@
[routerLinkActiveOptions]="{ exact: true }"
>首頁</a
>
<a [routerLink]="['task', 'list']" routerLinkActive="active">工作事項</a>
<a [routerLink]="['task', 'list']" routerLinkActive="active"
[queryParams]="{pageIdx:0, pageSize:5}"
>工作事項</a>
</nav>
<hr />
<router-outlet></router-outlet>

1
src/app/task-form-page/task-form-page.component.html

@ -3,5 +3,4 @@
<div>工作事項:<input type="text" [formControl]="formControl" /></div>
<div class="button">
<button type="button" (click)="onCancel()">取消</button>
<button type="button" (click)="onNext()">下一筆資料</button>
</div>

26
src/app/task-form-page/task-form-page.component.ts

@ -16,7 +16,7 @@ export class TaskFormPageComponent implements OnInit, OnDestroy {
readonly formControl = new FormControl();
// private readonly stop$ = new Subject<void>();
private readonly stop$ = new Subject<void>();
constructor(
private router: Router,
@ -24,17 +24,13 @@ export class TaskFormPageComponent implements OnInit, OnDestroy {
private taskService: TaskService
) {}
// 書本勘誤 p.9-12
// 錯誤內容:路由參數的訂閱需要手動去取消,否則會在每次頁面元件載入時都會建立一個訂閱。
// 正確內容:當元件裡有注入 ActivatedRoute,在 Router 建立元件時會一併建立 ActivatedRoute 實體,
// 而此元件被銷毀的同時,被注入至元件的 ActivatedRoute 實體也會一併被銷毀,因此不需要手動取消訂閱
ngOnInit(): void {
this.route.paramMap
.pipe(
map((paramMap) => paramMap.get('sn')),
switchMap((taskSn) => this.taskService.get(taskSn?taskSn:'')),
tap((task) => (this.task = task))
// takeUntil(this.stop$)
switchMap((taskSn) => this.taskService.get(taskSn??'')),
tap((task) => (this.task = task)),
takeUntil(this.stop$)
)
.subscribe({
next: (task) => this.formControl.setValue(task.TaskName),
@ -42,17 +38,15 @@ export class TaskFormPageComponent implements OnInit, OnDestroy {
}
ngOnDestroy(): void {
// this.stop$.next();
// this.stop$.complete();
this.stop$.next();
this.stop$.complete();
}
onNext(): void {
const sn = this.taskService.getNextSn(this.task.TaskSn);
// this.router.navigate(['task', 'form', sn]);
this.router.navigate([`../${sn}`], { relativeTo: this.route });
}
onCancel(): void {
this.router.navigateByUrl('tasks');
this.router.navigateByUrl('tasks'),{
queryParamsHandling: 'preserve',
}
}
}

4
src/app/task-page/task-page.component.html

@ -9,6 +9,10 @@
[task]="task"
(edit)="onEdit($event)"
></app-task>
<div class="pager">
<button type="button" (click)="onNextPage(-1)">上一頁</button>
<button type="button" (click)="onNextPage(1)">下一頁</button>
</div>
</ng-container>
<ng-template #empty>

51
src/app/task-page/task-page.component.ts

@ -1,6 +1,7 @@
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Observable } from 'rxjs';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Observable, Subject } from 'rxjs';
import { map, switchMap, takeUntil, tap } from 'rxjs/operators';
import { Task } from '../task';
import { TaskService } from '../task.service';
@ -12,10 +13,35 @@ import { TaskService } from '../task.service';
export class TaskPageComponent implements OnInit {
tasks$!: Observable<Task[]>;
constructor(private router: Router, private taskService: TaskService) {}
pageIndex!: number;
pageSize!: number;
constructor(
private router: Router,
private route: ActivatedRoute,
private taskService: TaskService
) {}
// 書本勘誤 p.9-12
// 錯誤內容:路由參數的訂閱需要手動去取消,否則會在每次頁面元件載入時都會建立一個訂閱。
// 正確內容:當元件裡有注入 ActivatedRoute,在 Router 建立元件時會一併建立 ActivatedRoute 實體,
// 而此元件被銷毀的同時,被注入至元件的 ActivatedRoute 實體也會一併被銷毀,因此不需要手動取消訂閱
ngOnInit(): void {
this.tasks$ = this.taskService.getList();
// const pageIndex = +this.route.snapshot.queryParamMap.get('pageIdx') || 1;
// const pageSize = +this.route.snapshot.queryParamMap.get('pageSize') || 5;
// this.tasks$ = this.taskService.getList(pageIndex, pageSize);
this.tasks$ = this.route.queryParamMap.pipe(
map((queryParamMap) => ({
index: +(queryParamMap.get('pageIdx') ?? 0),
size: +(queryParamMap.get('pageSize') || 5),
})),
tap(({ index, size }) => {
this.pageIndex = index;
this.pageSize = size;
}),
switchMap(({ index, size }) => this.taskService.getList(index, size))
);
}
onAdd(): void {
@ -23,6 +49,19 @@ export class TaskPageComponent implements OnInit {
}
onEdit(task: Task): void {
this.router.navigate(['task', 'form', task.TaskSn]);
this.router.navigate(['task', 'form', task.TaskSn], {
queryParamsHandling: 'preserve',
});
}
onNextPage(moveIndex: number): void {
this.router.navigate([], {
relativeTo: this.route,
queryParamsHandling: 'merge',
queryParams: {
pageIdx: this.pageIndex + moveIndex,
//pageSize: this.pageSize,
},
});
}
}

27
src/app/task.service.ts

@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map, tap } from 'rxjs/operators';
import { map, mergeMap, skip, take, toArray } from 'rxjs/operators';
import { Task } from './task';
@ -9,25 +9,20 @@ import { Task } from './task';
providedIn: 'root',
})
export class TaskService {
private _tasks: string[]=[];
constructor(private httpClient: HttpClient) {}
get(taskSn: string): Observable<any> {
return this.getList().pipe(
map((tasks) => tasks.find((task) => task.TaskSn === taskSn))
);
}
getNextSn(currentSn: string): string {
const index = this._tasks.findIndex((taskSn) => taskSn === currentSn);
const next = index === this._tasks.length - 1 ? 0 : index + 1;
return this._tasks[next];
return this.httpClient
.get<Task[]>('assets/tasks.json')
.pipe(map((tasks) => tasks.find((task) => task.TaskSn === taskSn)));
}
getList(): Observable<Task[]> {
return this.httpClient
.get<any>('../assets/tasks.json')
.pipe(tap((tasks) => (this._tasks = tasks.map((task) => task.TaskSn))));
getList(pageIndex = 0, pageSize = 10): Observable<Task[]> {
return this.httpClient.get<Task[]>('../assets/tasks.json').pipe(
mergeMap((task) => task),
skip(pageIndex * pageSize),
take(pageSize),
toArray()
);
}
}

24
src/assets/tasks.json

@ -2,5 +2,27 @@
{ "TaskSn": "001", "TaskName": "待辦事項 A" },
{ "TaskSn": "002", "TaskName": "待辦事項 B" },
{ "TaskSn": "003", "TaskName": "待辦事項 C" },
{ "TaskSn": "004", "TaskName": "待辦事項 D" }
{ "TaskSn": "004", "TaskName": "待辦事項 D" },
{ "TaskSn": "005", "TaskName": "待辦事項 E" },
{ "TaskSn": "006", "TaskName": "待辦事項 F" },
{ "TaskSn": "007", "TaskName": "待辦事項 G" },
{ "TaskSn": "008", "TaskName": "待辦事項 H" },
{ "TaskSn": "009", "TaskName": "待辦事項 I" },
{ "TaskSn": "010", "TaskName": "待辦事項 J" },
{ "TaskSn": "011", "TaskName": "待辦事項 K" },
{ "TaskSn": "012", "TaskName": "待辦事項 L" },
{ "TaskSn": "013", "TaskName": "待辦事項 M" },
{ "TaskSn": "014", "TaskName": "待辦事項 N" },
{ "TaskSn": "015", "TaskName": "待辦事項 O" },
{ "TaskSn": "016", "TaskName": "待辦事項 P" },
{ "TaskSn": "017", "TaskName": "待辦事項 Q" },
{ "TaskSn": "018", "TaskName": "待辦事項 R" },
{ "TaskSn": "019", "TaskName": "待辦事項 S" },
{ "TaskSn": "020", "TaskName": "待辦事項 T" },
{ "TaskSn": "021", "TaskName": "待辦事項 U" },
{ "TaskSn": "022", "TaskName": "待辦事項 V" },
{ "TaskSn": "023", "TaskName": "待辦事項 W" },
{ "TaskSn": "024", "TaskName": "待辦事項 X" },
{ "TaskSn": "025", "TaskName": "待辦事項 Y" },
{ "TaskSn": "026", "TaskName": "待辦事項 Z" }
]
Loading…
Cancel
Save