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

Angular 4 İle DoCheck Interface’i Kullanımı

Merhaba,

Biliyorsunuz ki, Angular uygulamaları birbirinden bağımsız componentler aracılığıyla programatize edilmekte ve bu bağımsız componentler modül yapısında birbirleriyle ilişkilendirilerek bütünsel hareket edilmesi sağlanmaktadır. Tabi süreçte bu uygulamalara ek olarak servis yapıları vs. dahil olmakta ve projenin inşası sürecinde birçok noktada birbirinden bağımsız ama birbirlerinin verisini yahut değerlerini kullanan katmansal yapılar ortaya çıkmaktadır. İşte bu tarz durumlarda, bir yapının içerisindeki kullanılan değerde/veride/veri kümesinde farklı bir yapı içerisinde oluşan değişiklik/güncelleme durumlarından ilgili yapı içerisinde haberdar olabilmek için tasarlanan DoCheck Interface’ini inceleyeceğiz.

Tabi ki de konuyu örnek bir senaryo üzerinden değerlendireceğiz.
Senaryomuzda; bir ürün listesine bir component üzerinden ekleme işlemi gerçekleştirirken diğer bir componentte ise istatiksel işlemler gerçekleştireceğiz. Her ürün eklendiğinde iki component için ortak olan ürün listesindeki yeni değişiklikleri DoCheck interface’i ile takip edecek ve istatiksel çalışmalara yenilikleri yansıtacağız.

O halde hemen başlayalım.

Öncelikle ürün modelimizi oluşturalım.

--- product.ts ---

export class Product {
    id: number;
    productName: string;
    stock: number;
    price: number;
}

Ardından veri kaynağı olarak kullanacağımız ürün listesini sabit olarak oluşturuyoruz.

--- product-list.ts ---

import { Product } from "./product";

export const ProductList: Product[] = [
    { id: 1, price: 100, stock: 50, productName: "Mouse" },
    { id: 2, price: 200, stock: 10, productName: "Monitör" },
    { id: 3, price: 4500, stock: 3, productName: "Televizyon" },
    { id: 4, price: 600, stock: 25, productName: "Kasa" },
    { id: 5, price: 120, stock: 17, productName: "Klavye" }
];

Şimdi istatiksel çalışmalar yapacağımız componentimizi oluşturalım.

--- product-statistics.components.ts ---

import { Component, OnInit } from '@angular/core';
import { ProductList } from "../entitys/product-list";
@Component({
  selector: 'app-product-statistics',
  templateUrl: './product-statistics.component.html',
  styleUrls: ['./product-statistics.component.css']
})
export class ProductStatisticsComponent implements OnInit {
  constructor() { }
  TotalPrice: number;
  TotalItem: number;
  ngOnInit() {
    this.TotalPrice = ProductList.reduce((a, b) => a = a + b.price, 0);
    this.TotalItem = ProductList.length;
  }
}

İstatistik componentimizin html görüntüsünüde ayarlayalım.

--- product-statistics.components.html ---

<div>
  <span>Ürün Adedi</span>
  {{TotalItem}}
</div>
<div>
  <span>Toplam Ürün Fiyatı</span>
  {{TotalPrice}}
</div>

Ve son olarak bu componenti yayınlamak için “app-product-statistics” seçicisini “app.component.html” dosyasında etiket olarak belirtelim.

Tabi bu belirtme işlemine gelmeden önce diğer componentimide oluşturmak istiyorum. Yani ürün listemize ekleme işlemini gerçekleştirecek olan componenti.

--- product-add.component.ts ---

import { Component, OnInit } from '@angular/core';
import { ProductList } from '../entitys/product-list';
import { Product } from '../entitys/product';
@Component({
  selector: 'app-product-add',
  templateUrl: './product-add.component.html',
  styleUrls: ['./product-add.component.css']
})
export class ProductAddComponent implements OnInit {
  constructor() { }
  ngOnInit() {  }
  addProduct() {
    let product = new Product();
    product.id = 6;
    product.price = 100;
    product.productName = "Yeni Eklenen Product";
    product.stock = 50;
    ProductList.push(product);
  }
}

Burada dikkat ederseniz eğer manuel olarak yeni bir product oluşturulup listeye eklenmiştir. Bunun sebebi Angular yazı dizimizin içeriksel hiyerarşisine itaatimdendir. Çünkü daha Angular 4 Form uygulamaları üzerine bir çalışma yayınlamadığımdan dolayı bu kısımda mevcut şekilde bir yönteme başvurmayı tercih etmiş bulunmaktayım.

Html kısmınıda inşa edersek eğer;

--- product-add.component.html ---

<button type="button" class="btn btn-primary" (click)="addProduct()">Ürün Ekle</button>

Evet… Şimdi bu componentin “app-product-add” seçicisinide “app.component.html” dosyasına etiket olarak belirtebiliriz.

--- app.component.html ---

<div class="panel panel-default">
    <div class="panel-body">İstatikler</div>
    <app-product-statistics></app-product-statistics>
</div>
<div class="panel panel-default">
    <div class="panel-body">Ürün Ekle</div>
    <app-product-add></app-product-add>
</div>

Çalışmanın görselinden anlaşılabilirliği arttırmak için bootsrap kullanılmıştır. Angular’a nasıl entegre edileceğini öğrenmek için buradaki makaleyi inceleyebilirsiniz.

Şimdi bu uygulamayı kaydedip, yayınlarsak eğer aşağıdaki gibi ürün eklemeye çalıştığımızda bir sorunla karşılaşılmaktadır.
Angular 4 İle DoCheck Interface'i Kullanımı
Programatik olarak ürünümüz listeleye eklensede bu değişiklik istatiksel neticeye yansımamaktadır.

Peki bunun sebebi nedir? sorusunun cevabını sizlerin verebiliyor olduğunuzu biliyorum. Lakin ola ki şu ana kadar gözden kaçırdığınız noktaların olabilmesi yahut farklı noktaya odaklanabilme ihtimalinizden dolayı bu durumun neden kaynaklandığını düşünemiyor olabilirsiniz. O yüzden cevabı çok kolay olan bu soruya bende karşılık vereceğim.

“product-statistics.component.ts” sınıfı içerisinde yapılan işlemler ürün listemizin gerekli istatiksel verilerini “ngOnInit” eventında elde etmekte ve bunları viewa yansıtmaktadır. Yani componentin ilk viewi açıldığında tetiklenen “ngOnInit” eventı tek seferliğine bu işlemi gerçekleştirmiş olmaktadır. Lakin aynı ürün listesini “product-add.component.ts” sınıfı kullanarak yeni veriler eklemekte ama bu yeniliklerden istatiksel componentimizin haberi olmamaktadır.

İşte böyle bir durum için “DoCheck” interface’i geliştirilmiştir. “@angular/core” altında bulunan bu interface, uygulama boyunca ilgili componente özel tanımlanmış tüm değerlere subscribe(abone) olmakta ve “ngDoCheck” isminde implement edeceği fonksiyon sayesinde bu değerlerdeki herhangi bir değişikliği bizlere bildirmektedir.

--- product-statistics.component.ts ---

import { Component, OnInit, DoCheck } from '@angular/core';
import { ProductList } from "../entitys/product-list";
@Component({
  selector: 'app-product-statistics',
  templateUrl: './product-statistics.component.html',
  styleUrls: ['./product-statistics.component.css']
})
export class ProductStatisticsComponent implements OnInit, DoCheck {
  constructor() { }
  TotalPrice: number;
  TotalItem: number;
  ngOnInit() {  }
  ngDoCheck() {
    this.TotalPrice = ProductList.reduce((a, b) => a = a + b.price, 0);
    this.TotalItem = ProductList.length;
  }
}

Yukarıdaki kod bloğunda görüldüğü üzere “ngOnInit” eventındaki komutlar “ngDoCheck” eventına alınmıştır. Bunun sebebi de biraz önce anlatmaya çalıştığım mantıkta hareket ederek, var olan yeniliklerde o yeni değerler üzerinden işlemler gerçekleştirmek için “ngDoCheck” eventında çalışılmaktadır.

İşte bu şekilde uygulamamızı kaydedip, yayınladığımızda aşağıdaki gibi çalıştığını görebileceksiniz.
Angular 4 İle DoCheck Interface'i Kullanımı

Bu içeriğimizde birbirinden bağımsız çalışan ama ortak veri yapılarını kullanan componentler üzerinde gerçekleşecen verisel işlemlerin, tüm componentlerde nasıl takip edildiğini ve bu işlem için DoCheck interface’inin nasıl kullanıldığına değinmiş olduk.

Bol bol faydalanmanız dileğiyle…

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

Bunlar da hoşunuza gidebilir...

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir