สารบัญเนื้อหา
1. เพิ่มระบบ Sorting ใน API
เพิ่ม OrderBy ใน UserParams.cs ใน API
public string OrderBy { get; set; }
namespace SocialApp_API.Helpers
{
public class UserParams
{
private const int MaxPageSize = 50;
public int PageNumber { get; set; } = 1;
private int pageSize = 10;
public int PageSize
{
get { return pageSize; }
set { pageSize = (value > MaxPageSize) ? MaxPageSize : value; }
}
public int UserId { get; set; }
public string Gender { get; set; }
public int MinAge { get; set; } = 18;
public int MaxAge { get; set; } = 99;
public string OrderBy { get; set; }
}
}
เพิ่มการ Order ใน GetUsers() ของ SocialRepository.cs
public async Task<PagedList<User>> GetUsers(UserParams userParams)
{
var users = _context.Users.Include(p => p.Photos)
.OrderByDescending(u => u.LastActive).AsQueryable();
users = users.Where(u => u.Id != userParams.UserId);
users = users.Where(u => u.Gender == userParams.Gender);
if (userParams.MinAge != 18 || userParams.MaxAge != 99)
{
var minDob = DateTime.Today.AddYears(-userParams.MaxAge - 1);
var maxDob = DateTime.Today.AddYears(-userParams.MinAge);
users = users.Where(u => u.DateOfBirth >= minDob && u.DateOfBirth <= maxDob);
}
if (!string.IsNullOrEmpty(userParams.OrderBy))
{
switch (userParams.OrderBy)
{
case "created":
users = users.OrderByDescending(u => u.Created);
break;
default:
users = users.OrderByDescending(u => u.LastActive);
break;
}
}
return await PagedList<User>.CreateAsync(users, userParams.PageNumber, userParams.PageSize);
}
ทดสอบเรียก API
http://localhost:5000/api/users
http://localhost:5000/api/users?orderBy=created
2. การทำ Sorting ใน SPA
เราจะใช้ ButtonModule จาก ngx-module โดยเริ่มทำการ import ใน app.module.ts
import { ButtonsModule } from 'ngx-bootstrap/buttons';
ButtonsModule.forRoot(),
เพิ่มการ Order ใน onInit() ของ member-list.component.ts
this.userParams.orderBy = 'lastActive';
member-list.component.ts ฉบับเต็ม
import { Component, OnInit } from '@angular/core';
import { User } from '../../_models/user';
import { UserService } from '../../_services/user.service';
import { AlertifyService } from '../../_services/alertify.service';
import { ActivatedRoute } from '@angular/router';
import { Pagination, PaginatedResult } from 'src/app/_models/pagination';
@Component({
selector: 'app-member-list',
templateUrl: './member-list.component.html',
styleUrls: ['./member-list.component.css']
})
export class MemberListComponent implements OnInit {
users: User[];
user: User = JSON.parse(localStorage.getItem('user'));
genderList = [{value: 'male', display: 'Males'}, {value: 'female', display: 'Females'}];
userParams: any = {};
pagination: Pagination;
constructor(private userService: UserService, private alertify: AlertifyService, private route: ActivatedRoute) { }
ngOnInit() {
this.route.data.subscribe(data => {
this.users = data.users.result;
this.pagination = data.users.pagination;
});
this.userParams.gender = this.user.gender === 'female' ? 'male' : 'female';
this.userParams.minAge = 18;
this.userParams.maxAge = 99;
this.userParams.orderBy = 'lastActive';
}
resetFilters() {
this.userParams.gender = this.user.gender === 'female' ? 'male' : 'female';
this.userParams.minAge = 18;
this.userParams.maxAge = 99;
this.loadUsers();
}
pageChanged(event: any): void {
this.pagination.currentPage = event.page;
this.loadUsers();
}
loadUsers() {
this.userService
.getUsers(this.pagination.currentPage, this.pagination.itemsPerPage, this.userParams)
.subscribe((res: PaginatedResult<User[]>) => {
this.users = res.result;
this.pagination = res.pagination;
}, error => {
this.alertify.error(error);
});
}
}
เพิ่มปุ่มสำหรับ Sorting ด้านหลังของปุ่ม ResetFilter ใน member-list.component.html
<div class="col">
<div class="btn-group float-right">
<button type="button" name="orderBy" class="btn btn-primary" [(ngModel)]="userParams.orderBy" (click)="loadUsers()" btnRadio="lastActive">Last Active</button>
<button type="button" name="orderBy" class="btn btn-primary" [(ngModel)]="userParams.orderBy" (click)="loadUsers()" btnRadio="created">Newest Members</button>
</div>
</div>
member-list.component.html ฉบับเต็ม
<div class="text-center mt-3">
<h2>Your matches - {{pagination.totalItems}} found</h2>
</div>
<div class="container mt-3">
<form class="form-inline" #form="ngForm" (ngSubmit)="loadUsers()" novalidate>
<div class="form-group">
<label for="minAge">Age From</label>
<input type="number" class="form-control ml-1" style="width: 70px" id="minAge"
[(ngModel)]="userParams.minAge" name="minAge">
</div>
<div class="form-group px-2">
<label for="maxAge">Age To</label>
<input type="number" class="form-control ml-1" style="width: 70px" id="maxAge"
[(ngModel)]="userParams.maxAge" name="maxAge">
</div>
<div class="form-group px-2">
<label for="gender">Show: </label>
<select class="form-control ml-1" style="width: 130px" id="gender"
[(ngModel)]="userParams.gender" name="gender">
<option *ngFor="let gender of genderList" [value]="gender.value">
{{gender.display}}
</option>
</select>
</div>
<button type="submit" class="btn btn-primary" style="margin-left:10px">Apply Filters</button>
<button type="button" class="btn btn-info" (click)="resetFilters()" style="margin-left:10px">Reset Filter</button>
<div class="col">
<div class="btn-group float-right">
<button type="button" name="orderBy" class="btn btn-primary" [(ngModel)]="userParams.orderBy" (click)="loadUsers()" btnRadio="lastActive">Last Active</button>
<button type="button" name="orderBy" class="btn btn-primary" [(ngModel)]="userParams.orderBy" (click)="loadUsers()" btnRadio="created">Newest Members</button>
</div>
</div>
</form>
<br>
<div class="row">
<div *ngFor="let user of users" class="col-lg-2 col-md-3 col-sm-6">
<app-member-card [user]="user"></app-member-card>
</div>
</div>
</div>
<div class="d-flex justify-content-center">
<pagination [boundaryLinks]="true"
[totalItems]="pagination.totalItems"
[itemsPerPage]="pagination.itemsPerPage"
[(ngModel)]="pagination.currentPage"
(pageChanged)="pageChanged($event)"
previousText="‹" nextText="›" firstText="«" lastText="»">
</pagination>
</div>
เพิ่มพารามิเตอร์สำหรับ Sorting ใน user.service.ts
if (userParams != null) {
params = params.append('minAge', userParams.minAge);
params = params.append('maxAge', userParams.maxAge);
params = params.append('gender', userParams.gender);
params = params.append('orderBy', userParams.orderBy);
}
user.service.ts ฉบับเต็ม
import { Injectable } from '@angular/core';
import { environment } from 'src/environments/environment';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';
import { User } from '../_models/user';
import { PaginatedResult } from '../_models/pagination';
import { map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class UserService {
baseUrl = environment.apiUrl;
constructor(private http: HttpClient) { }
getUsers(page?, itemsPerPage?, userParams?): Observable<PaginatedResult<User[]>> {
const paginatedResult: PaginatedResult<User[]> = new PaginatedResult<User[]>();
let params = new HttpParams();
if (page != null && itemsPerPage != null) {
params = params.append('pageNumber', page);
params = params.append('pageSize', itemsPerPage);
}
if (userParams != null) {
params = params.append('minAge', userParams.minAge);
params = params.append('maxAge', userParams.maxAge);
params = params.append('gender', userParams.gender);
params = params.append('orderBy', userParams.orderBy);
}
return this.http.get<User[]>(this.baseUrl + 'users', { observe: 'response', params })
.pipe(
map(response => {
paginatedResult.result = response.body;
if (response.headers.get('Pagination') != null) {
paginatedResult.pagination = JSON.parse(response.headers.get('pagination'));
}
return paginatedResult;
})
);
}
getUser(id): Observable<User> {
return this.http.get<User>(this.baseUrl + 'users/' + id);
}
updateUser(id: number, user: User) {
return this.http.put(this.baseUrl + 'users/' + id, user);
}
setMainPhoto(userId: number, id: number) {
return this.http.post(this.baseUrl + 'users/' + userId + '/photos/' + id + '/setMain', {});
}
deletePhoto(userId: number, id: number) {
return this.http.delete(this.baseUrl + 'users/' + userId + '/photos/' + id);
}
}
ทดสอบรันและใช้งาน