Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

Angular 4 – Slice Pipe İle Sayfalama

Merhaba,

Bu içeriğimizde Angular uygulamalarında Slice Pipe ile sayfalama işlemini irdeleyeceğiz. Tabi öncelikli olarak Slice Pipe’ın yapısal özelliğini detaylıca inceleyecek ve ardından bu filtreyi sayfalama tekniği üzerinde kullanacağız.

Slice Pipe; dizi, koleksiyon vs. gibi veri kümelerinde belirli aralıklardaki verilere ulaşmamızı sağlayan bir yapıya sahiptir. Kullanım prototipi aşağıdaki gibidir;

[VERİ KÜMESİ] | slice : [DEĞER ARALIĞI]

Slice Pipe’ın kullanımını anlayabilmek için öncelikle veri kümelerindeki indexel değerlerin hangi mantıkta olduğunu bilmek gerekmektedir. Aşağıda bir veri kümesindeki verilerin indexel değerini resmetmeye çalışmış bulunmaktayım.

Angular 4 - Slice Pipe İle Sayfalama

Görseli incelerseniz eğer “Gençay Yıldız” string değeri bizim için bir veri kümesi mahiyetindedir. Her yazılımcı bilir ki, string bir ifade aslen bir char dizisidir. Yani char veri kümesi. Bu bir temel programlama bilgisidir. O halde bu string tipteki veri kümesini ele aldığımızda indexel değerleri soldan sağa 0’dan başlayarak birer birer artmakta ve sağdan sola ise -1’den başlayarak birer birer düşmektedir. Bu tüm veri kümeleri için genelleştirilebilir bir bilgidir.

Bu bilgi ışında aşağıdaki örnek kodları yorumlamanız Slice Pipe kullanımı ve mantığı açısından netleştirici olacaktır.

  • {{"GençayYıldız" | slice : 5 : 9}}
    

    Çıktı : “yYıl”

  • {{"GençayYıldız" | slice : 3 : -2}}
    

    Çıktı : “çayYıld”

  • {{"GençayYıldız" | slice : -5}}
    

    Çıktı : “ıldız”

  • {{"GençayYıldız" | slice : 5}}
    

    Çıktı : “yYıldız”

Örnek kodlarda alınan çıktılara göz atarsanız eğer ufak bir göz gezdirmeyle mantığı direkt olarak kavranabileceğinden dolayı Slice Pipe’ın parametreler arasındaki ilişkisine değinme gereği duymuyorum.

Dolayısıyla Slice Pipe’ın hangi mantıkta ve nasıl çalıştığını görmüş bulunmaktasınız. Haliyle şimdi sıra bir Angular uygulamasında bu filtre eşliğinde örnek bir sayfalama yapımını ele almaya geldi.

Örnek senaryomuzda product listesi söz konusu olacaktır. İşlevsel olarak basit bir senaryo olacağından dolayı teorik detaylara fazla takılmadan hızlıca pratiğe geçelim.

Öncelikle “product.js” dosyamızı oluşturalım ve içerisine sınıfımızı aşağıdaki özelliklerle tanımlayalım.

export class Product {
    productName: string;
    Stock: number;
    price: number;
}

Veri kaynağı teşkil etmesi açısından aşağıdaki gibi “product-list.ts” dosyamızı oluşturalım ve içerisine “Product” dizisi tipinden sabit tanımlayarak bu sabit içerisine de farklı product nesneleri tanımlayalım.

import { Product } from "./product";

export const ProductList: Product[] = [
    { productName: "Ütü", price: 100, Stock: 100 },
    { productName: "Sandalye", price: 25, Stock: 100 },
    { productName: "Dolap", price: 55, Stock: 100 },
    { productName: "Bardak", price: 5, Stock: 100 },
    { productName: "Buzdolabı", price: 1200, Stock: 100 },
    { productName: "Televizyon", price: 1020, Stock: 100 },
    { productName: "Koltuk Takımı", price: 1300, Stock: 100 },
    { productName: "Yemek Takımı", price: 1400, Stock: 100 },
    { productName: "Perde", price: 125, Stock: 100 },
    { productName: "Halı", price: 55, Stock: 100 },
    { productName: "Kanepe", price: 65, Stock: 100 },
    { productName: "Yatak", price: 435, Stock: 100 },
    { productName: "Çamaşır Sepeti", price: 55, Stock: 100 },
];

Şimdi sıra bu verileri listelemeye geldi.

“Product” isminde bir component oluşturalım ve “product.component.html” dosyasında aşağıdaki çalışmayı yapalım.

import { Component, OnInit } from '@angular/core';
import { Product } from '../entitys/product';
import { ProductList } from '../entitys/product-list';

@Component({
  selector: 'app-product',
  templateUrl: './product.component.html',
  styleUrls: ['./product.component.css']
})
export class ProductComponent implements OnInit {
  productList: Product[];
  constructor() { }
  ngOnInit() {
    this.productList = ProductList;
  }
}
<div class="row">
    <div class="list-group">
      <a class="list-group-item list-group-item-action" *ngFor="let product of productList">{{product.productName}} <br>Stock : {{product.stock}} <br>Price : {{product.price}}</a>
    </div>
  </div>

Ve ardından ana componentimizin(AppComponent) view dosyası olan “app.component.html” dosyasında product componentin selector değerini belirterek ilgili componenti yayınlayalım.

<app-product></app-product>

Tüm bu işlemlerden sonra uygulamayı kaydedip, çalıştırdığımız zaman “ProductList” veri kümesindeki tüm productların listelendiğini göreceğiz.

Şimdi sıra bu listeyi sayfalamaya geldi.

İlk olarak sayfalama bilgilerini tutacak “Pager.ts” isimli sınıfımızı oluşturalım.

export class Pager {
    pageList: Array<number> = [];
    currentPage: number;
    pageSize: number;
}

Yukarıdaki sınıfta; “pageList” özelliği, 1’den sayfa adedine kadar olan tüm değerleri bir dizi olarak tutmaktadır; “currentPage” özelliği, o anki sayfa bilgisini tutmaktadır ve “pageSize” özelliği ise bir sayfada kaç adet product listeleneceği bilgisini tutmaktadır.

Şimdi “ProductComponent” sınıfımıza gelip “Pager” nesnesi oluşturabileceğimiz “getPager” isimli bir fonksiyon yazalım ve ardından “pager” isminde bir referans oluşturarak “ngOnInit” eventında ilgili referansa oluşturmuş olduğumuz “getPager” fonksiyonu sayesinde bir “Pager” nesnesi atayalım.

import { Component, OnInit } from '@angular/core';
import { Product } from '../entitys/product';
import { ProductList } from '../entitys/product-list';
import { Pager } from '../pager';
@Component({
  selector: 'app-product',
  templateUrl: './product.component.html',
  styleUrls: ['./product.component.css']
})
export class ProductComponent implements OnInit {
  productList: Product[];
  pager: Pager;
  constructor() { }
  ngOnInit() {
    this.productList = ProductList;
    this.pager = this.getPager(this.productList.length);
  }
  getPager(totalItem: number, pageSize: number = 3, currentPage: number = 1): Pager {
    let pager = new Pager();
    pager.pageSize = Math.ceil(totalItem / pageSize);
    pager.currentPage = currentPage;
    for (let i = 1; i <= Math.ceil(totalItem / pageSize); i++)
      pager.pageList.push(i);
    return pager;
  }
}

Ve bu işlemden sonra “product.component.html” sayfasına gelerek sayfalama linklerini ekleyelim.

<div class="row">
  <div class="list-group">
    <a class="list-group-item list-group-item-action" *ngFor="let product of productList">{{product.productName}}
      <br>Stock : {{product.stock}}
      <br>Price : {{product.price}}</a>
  </div>
</div>

<nav aria-label="Page navigation example">
  <ul class="pagination">
    <li *ngFor="let page of pager.pageList" class="page-item">
      <a class="page-link">{{page}}</a>
    </li>
  </ul>
</nav>

Tabi bu linkler bootsrap yardımıyla rahat bir şekilde oluşturulabilmektedir. Bu makale Angular 4 Yazı Dizisi‘nin bir parçası olduğundan dolayı alt yapı olarak yan uygulamaların projeye nasıl entegrasyon edildiğine değinilmemekte, edildiği varsayılmaktadır. Sizler direkt olarak bu makaleyi inceliyorsanız eğer Angular 4 – Third Party Paket Entegrasyonu ve Kullanımı başlıklı makalemden boostrap, jQuery vs. gibi üçüncü parti paketlerin entegrasyonunu inceleyebilirsiniz.

Yapılan bu son işlem neticesinde projemizi kaydedip, yayınladığımızda aşağıdaki gibi sayfa numaralarının oluştuğu lakin adreslerinin verilmediği ve bununla beraber veri kümesinin hala tam olarak listelendiği durumlarıyla karşılaşacağız.
Angular 4 - Slice Pipe İle Sayfalama

Şu durumda öncelikli olarak sayfa numaralarına adreslerini vermekle başlayalım. Bu iş için route tanımlamamız gerekecektir. Angular 4 Routing Mekanizması başlıklı makalede teknik boyutunu ele aldığımız gibi sayfa numaralarına özel route tanımlayacağız.

Hemen routes yapımızı aşağıdaki gibi oluşturuyoruz.

const appRoutes: Routes = [
  { path: "", redirectTo: "/page", pathMatch: "full" },
  { path: "page", component: ProductComponent }
];

Ardından tıklanan sayfa numarasını elde edebilmek için sayfa numaralarının “click” eventına “setPage” isminde bir fonksiyon tanımlayalım ve “product.component.ts” dosyasında bu fonksiyonu oluşturalım.

<nav aria-label="Page navigation example">
  <ul class="pagination">
    <li *ngFor="let page of pager.pageList" class="page-item" [class.active]="page == pager.currentPage">
      <a class="page-link" (click)="setPage(page)">{{page}}</a>
    </li>
  </ul>
</nav>
  setPage(page: number) {
    this.pager.currentPage = page;
  }

Tüm bu işlemler neticesinde artık hangi aralıklarda kaç adet veriye erişeceğimizi “Pager” nesnesindeki veriler sayesinde biliyoruz. Son olarak yapmamız gereken “Pager” nesnesindeki verileri ilgili veri kümemize Slice Pipe uygularken parametrik değerler olarak vermek kalıyor.

<div class="row">
  <div class="list-group">
    <a class="list-group-item list-group-item-action" *ngFor="let product of productList | slice : (pager.currentPage - 1) * pager.pageSize : ((pager.currentPage - 1) * pager.pageSize) + pager.pageSize">{{product.productName}}
      <br>Stock : {{product.stock}}
      <br>Price : {{product.price}}</a>
  </div>
</div>

Bu şekilde projemizi kaydedip, yayınladığımızda aşağıdaki gibi sayfalama işleminin başarıyla gerçekleştiğini göreceksiniz.
Angular 4 - Slice Pipe İle Sayfalama

Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Bunlar da hoşunuza gidebilir...

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir