第37天~

这个得上一篇:https://ithelp.ithome.com.tw/articles/10258274

回到product-list-grid.component.html档案:

限定最多只能显示5页
https://ithelp.ithome.com.tw/upload/images/20210817/20119035n1qwVzKhzo.png
https://ithelp.ithome.com.tw/upload/images/20210817/20119035fZHbTS8hhq.png

再来显示最头<<最尾页>>.加入语法:[boundaryLinks]="true"
https://ithelp.ithome.com.tw/upload/images/20210817/20119035awBNryomWL.png

https://ithelp.ithome.com.tw/upload/images/20210817/20119035LZF9paHfvY.png

<div class="main-content">
  <div class="section-content section-content-p30">
    <div class="container-fluid">
      <div class="row">

        <!--内容区的显示-->
        <div *ngFor="let tempProduct of products" class="col-md-3">

          <div class="product-box">

            <a routerLink="/products/{{ tempProduct.id }}">


              <img src="{{ tempProduct.imageUrl }}" class="img-responsive">
            </a>

            <a routerLink="/products/{{ tempProduct.id }}">

              <h1>{{ tempProduct.name}}</h1>

            </a>
            <div class="price">{{ tempProduct.unitPrice | currency:'USD'}}</div>
            <a href="#" class="primary-btn">Add to cart</a>

          </div>
        </div>

        <div *ngIf="products?.length ==0" class="alert alert-warning col-md-12" role="alert">
          找不到这个品项

        </div>


      </div>
      <!--begin footer-->>
      <div class="footer-pagination">
        <div class="row">
          <div class="col-md-6"></div>

          <div class="col-md-6">
            <div class="row">

              <div class="col-md-9" style="padding-left: 30%">

                <ngb-pagination [(page)]="thePageNumber"
                                 [(pageSize)]="thePageSize"
                                 [(collectionSize)]="theTotalElements"
                                 [maxSize]="5"
                                 [boundaryLinks]="true"
                                 (pageChange)="listProducts()">



                </ngb-pagination>

              </div>

               <div class="col-md-3 mt-2" style="text-align: right;">
                <span class="mr-2">Page Size</span>

                <select (change)="updatePageSize($event.target.value)">
                  <option>2</option>


                  <option selected="true">5</option>
                  <option>10</option>
                  <option>20</option>
                  <option>50</option>

                </select>


               </div>



            </div>

          </div>

        </div>

      </div>

    </div>
  </div>
</div>

接下来是要增加关键字的搜寻
到product.service.ts 档案.
https://ithelp.ithome.com.tw/upload/images/20210817/201190355SfnyRRYDa.png
先复制这段:

https://ithelp.ithome.com.tw/upload/images/20210817/20119035buRxYQxZiJ.png
然後变更 getProductListPaginate名字为searchProductsPaginate

再来更改编写程序码:

import { Product } from 'src/app/common/product';
import { ProductCategory } from './../common/product-category';
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class ProductService {

  private baseUrl = 'http://localhost:8080/api/products';

  private categoryUrl = 'http://localhost:8080/api/product-category';

  constructor(private httpClient: HttpClient) { }

  getProduct(theProductId: number): Observable<Product> {

    const productUrl = `${this.baseUrl}/${theProductId}`;

    return this.httpClient.get<Product>(productUrl);

  }

  getProductListPaginate(thePage: number,
    thePageSize: number,
    theCategoryId: number): Observable<GetResponseProducts> {

    const searchUrl = `${this.baseUrl}/search/findByCategoryId?id=${theCategoryId}`
      + `&page=${thePage}&size=${thePageSize}`;

    return this.httpClient.get<GetResponseProducts>(searchUrl);
  }


  getProductList(theCategoryId: number): Observable<Product[]> {

    const searchUrl = `${this.baseUrl}/search/findByCategoryId?id=${theCategoryId}`;

    return this.getProducts(searchUrl);
  }

  searchProducts(theKeyword: string): Observable<Product[]> {

    const searchUrl = `${this.baseUrl}/search/findByNameContaining?name=${theKeyword}`;

    return this.getProducts(searchUrl);

  }
  searchProductsPaginate(thePage: number,
                         thePageSize: number,
                         theKeyword:string): Observable<GetResponseProducts> {

    const searchUrl = `${this.baseUrl}/search/findByNameContaining?name=${theKeyword}`
                    + `&page=${thePage}&size=${thePageSize}`;

    return this.httpClient.get<GetResponseProducts>(searchUrl);
  }



  private getProducts(searchUrl: string): Observable<Product[]> {
    return this.httpClient.get<GetResponseProducts>(searchUrl).pipe(
      map(response => response._embedded.products)

    );
  }

  getProductCategories(): Observable<ProductCategory[]> {


    return this.httpClient.get<GetResponseProductCategory>(this.categoryUrl).pipe(
      map(response => response._embedded.productCategory)
    );
  }
}

interface GetResponseProducts {
  _embedded: {
    products: Product[];
  },
  page: {
    size: number,
    totalElements: number,
    totalPages: number,
    number: number
  }

}

interface GetResponseProductCategory {
  _embedded: {
    productCategory: ProductCategory[];
  }
}

再到product-list.component.ts档案:
https://ithelp.ithome.com.tw/upload/images/20210817/20119035GHcc5kFx3f.png

import { Component, OnInit } from '@angular/core';
import { ProductService } from 'src/app/services/product.service';
import { Product } from 'src/app/common/product';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-product-list',

  templateUrl: './product-list-grid.component.html',

  styleUrls: ['./product-list.component.css']
})
export class ProductListComponent implements OnInit {

  products: Product[];
  currentCategoryId: number = 1;
  previousCategoryId: number=1;
  searchMode: boolean = false;

  thePageNumber: number = 1;
  thePageSize: number = 5;
  theTotalElements: number = 0;

  previousKeyword: string=null;


  constructor(private productService: ProductService,
    private Route: ActivatedRoute) { }

  // tslint:disable-next-line: typedef
  ngOnInit() {
    this.Route.paramMap.subscribe(() => {
      this.listProducts();
    });
  }

  // tslint:disable-next-line: typedef
  listProducts() {

    this.searchMode = this.Route.snapshot.paramMap.has('keyword');

    if (this.searchMode) {
      this.handleSearchProducts();
    }
    else {
      this.handleListProducts();
    }


  }

  handleSearchProducts() {

    const theKeyword: string = this.Route.snapshot.paramMap.get('keyword');

    if(this.previousKeyword != theKeyword){
      this.thePageNumber =1;
    }

    this.previousKeyword =theKeyword;

    console.log(`keyword=${theKeyword},thePageNumber=${this.thePageNumber}`);

    this.productService.searchProductsPaginate(this.thePageNumber -1,
                                               this.thePageSize,
                                               theKeyword).subscribe(this.processResult());


  }



  handleListProducts() {
    const hasCategoryId: boolean = this.Route.snapshot.paramMap.has('id');

    if (hasCategoryId) {
      this.currentCategoryId = +this.Route.snapshot.paramMap.get('id');
    }
    else {
      this.currentCategoryId = 1;
    }

    if (this.previousCategoryId != this.currentCategoryId) {
      this.thePageNumber = 1;

    }

    this.previousCategoryId=this.currentCategoryId;

    console.log(`currentCategoryId=${this.currentCategoryId},thePageNumber=${this.thePageNumber}`);


    this.productService.getProductListPaginate(this.thePageNumber -1,
      this.thePageSize,
      this.currentCategoryId)
      .subscribe(this.processResult());

    }

processResult(){
  return data =>{
    this.products=data._embedded.products;
    this.thePageNumber=data.page.number +1;
    this.thePageSize =data.page.size;
    this.theTotalElements =data.page.totalElements;

  };
  }


  updatePageSize(pageSize: number){
    this.thePageSize=pageSize;
    this.thePageNumber=1;
    this.listProducts();
  }
}



搜寻python
https://ithelp.ithome.com.tw/upload/images/20210817/2011903591bqy0JEaZ.png

这个的下一篇:https://ithelp.ithome.com.tw/articles/10258345


<<:  多线程(Multithreading)

>>:  第38天~

Day17 - 语音辨识神级工具-Kaldi part2

首先介绍的是发音词典处理,我们必须先准备一份发音词典(lexicon),格式会长得像以下的样子。左边...

Day 07 : MLOps 的挑战与技术要求

在 Day 06 引用与介绍 3 个 MLOps 相关定义,如果 MLOps 是一种工程文化与实践,...

知识工作者的管理

在上一篇我分享过我对「工作的意义与价值」的观察。读过後,你该不难理解为何当年 Jack Welch...

Linkedin Java 检定题目分享

前言 在更新Linkedkin 个人档案的时候 偶然发现他有技术检定测验 如果总成绩在前30%,会发...

树选手2号:random forest [python实例]

今天来用前几天使用判断肿瘤良性恶性的例子来执行random forest,一开始我们一样先建立sco...