[ตอนที่ 16] Social App Workshop ด้วย ASP.NET Core 3 กับ Angular 9 การทำ Sorting

Line
Facebook
Twitter
Google

สารบัญเนื้อหา

  1. เพิ่มระบบ Sorting ใน API
  2. การทำ Sorting ใน SPA

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);
  }

}

ทดสอบรันและใช้งาน

Line
Facebook
Twitter
Google
การติดตั้งและใช้งาน Datatables ร่วมกับ Angular
[ตอนที่ 16] Social App Workshop ด้วย ASP.NET Core 3 กับ Angular 9 การทำ Sorting
[ตอนที่ 15] Social App Workshop ด้วย ASP.NET Core 3 กับ Angular 9 การทำ Filtering
[ตอนที่ 14] Social App Workshop ด้วย ASP.NET Core 3 กับ Angular 9 การใช้งาน Paging
เตรียม Atom สำหรับ React Native #3
เตรียม Visual Studio Code สำหรับ React Native #2
การติดตั้ง React Native บน macOs #1
การกำหนดค่า TF_MIN_GPU_MULTIPROCESSOR_COUNT เพื่อให้ TensorFlow ใช้งาน GPU ทุกตัว
ติดตั้ง Ubuntu 17.04 ใช้งานร่วมกับ Windows 10
การติดตั้ง TensorFlow & Caffe บน Ubuntu 16.04