Physical Address

304 North Cardinal St.
Dorchester Center, MA 02124

Angular 101: Mastering the Basics

Angular, dinamik ve etkileyici kullanıcı arayüzleri oluşturmanıza yardımcı olur. Ayrıca, uygulamanızın daha organize, bakımı kolay ve genişletilebilir olmasını sağlar. Bununla birlikte, Angular'ı kullanmaya başlamadan önce, bazı önemli kavramları anlamak önemlidir. 🚀📘

Core Building Blocks

Angular decorators

Angular uygulamalarının temel yapı taşlarından biri olan dekoratörler (decorators), Angular’da bileşenlerin, hizmetlerin, modüllerin ve diğer yapıların işlevselliğini genişletmek için kullanılan güçlü bir özelliktir. Bir dekoratör, bir nesneye ek özellikler eklemek için kullanılan bir tasarım desenidir. Angular, TypeScript ile geliştirildiği için dekoratörler TypeScript tarafından desteklenen bir özelliktir.

Angular’da yaygın olarak kullanılan bazı dekoratörler şunlardır:

  1. @Component: Bir bileşenin tanımlanması için kullanılır.
  2. @Directive: Bir direktifin tanımlanması için kullanılır.
  3. @Injectable: Bir servisin tanımlanması için kullanılır.
  4. @NgModule: Bir modülün tanımlanması için kullanılır.
  5. @Input: Bir bileşene dışarıdan veri girişi sağlamak için kullanılır.
  6. @Output: Bir bileşenden dışarı veri çıkışı sağlamak için kullanılır.
  7. @ViewChild ve @ViewChildren: Bir bileşenin veya elemanların bir görünüm ağacındaki referanslarını almak için kullanılır.

Bu dekoratörlerin her biri, belirli bir yapıya veya bileşene özel işlevselliği sağlar. Örneğin, @Component dekoratörü bir bileşenin belirli bir bileşen olduğunu tanımlar ve bu bileşene ait metadataları sağlar.

import { Component } from '@angular/core';

@Component({
  selector: 'app-example',
  template: '<p>This is an example component</p>',
  styleUrls: ['./example.component.css']
})
export class ExampleComponent {
  // Component logic goes here
}

Yukarıdaki örnekte, @Component dekoratörü, ExampleComponent sınıfını bir bileşen olarak tanımlar. Bu dekoratör, bir bileşenin nasıl görüneceği, nerede kullanılacağı ve hangi stillere sahip olacağı gibi metadataları sağlar.

@Directive dekoratörü ise, bir HTML elemanının davranışını değiştirmek için kullanılır. Örneğin, bir fare tıklaması sonrası belirli bir işlevi gerçekleştirmek üzere bir elementi etkinleştirebiliriz.

import { Directive, HostListener } from '@angular/core';

@Directive({
  selector: '[appCustomDirective]'
})
export class CustomDirective {
  constructor() { }

  @HostListener('click') onClick() {
    console.log('Element clicked');
  }
}

Yukarıdaki örnekte, @Directive dekoratörü, CustomDirective adlı bir direktifi tanımlar. Bu direktif, HTML’de appCustomDirective seçicisiyle belirtilen herhangi bir element için tıklama olayını dinler ve bir konsol mesajı görüntüler.

Bu örnekler, Angular dekoratörlerinin nasıl kullanıldığını ve bileşenlerin, direktiflerin ve hizmetlerin nasıl tanımlanacağını göstermektedir. Angular, bu dekoratörler sayesinde bileşen tabanlı bir yapı sunar ve geliştiricilere uygulamalarını modüler ve yönetilebilir hale getirme imkanı sağlar.

Angular modules

Angular’da modüller (modules), uygulamanızı mantıksal ve fiziksel olarak parçalara ayırmanın anahtarıdır. Modüller, uygulamanızı organize etmek, yeniden kullanılabilirlik sağlamak ve kodunuzu daha iyi yönetmek için kullanılan bir yapıdır. Angular uygulamalarında genellikle bir veya daha fazla modül bulunur ve bu modüllerin hiyerarşik bir yapı oluşturabileceği bir modül ağacı oluşturulabilir.

Angular’da modüllerin başlıca görevleri şunlardır:

  1. Bileşenleri, direktifleri, servisleri ve diğer kod parçalarını gruplama: Modüller, birlikte çalışan bileşenleri ve diğer Angular öğelerini gruplamak için kullanılır. Bu, uygulamanızı daha organize hale getirir ve büyüdükçe yönetmesi daha kolay hale gelir.
  2. Bağımlılıkları yönetme: Modüller, uygulamanızın bağımlılıklarını yönetmenize yardımcı olur. Angular, modül sistemi sayesinde bağımlılıkları bildirir ve enjekte eder, böylece bileşenleriniz ve hizmetleriniz kolayca birbirleriyle iletişim kurabilir.
  3. Lazy Loading: Modüller, Angular uygulamanızı daha etkin bir şekilde yüklemek ve performansı artırmak için kullanılabilir. Özellikle büyük uygulamalar için, belirli modülleri yalnızca gerektiğinde yüklemek (lazy loading) uygulamanın başlangıç yüklemesini azaltabilir.

Angular’da bir modül oluşturmak için @NgModule dekoratörü kullanılır. Bu dekoratör, bir JavaScript nesnesi ile bir modül sınıfını tanımlar. Bu sınıf genellikle NgModule adını alır ve imports, exports, declarations, ve providers gibi özelliklere sahip olabilir.

Örnek bir modül:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';

import { HeaderComponent } from './header/header.component';
import { FooterComponent } from './footer/footer.component';
import { SidebarComponent } from './sidebar/sidebar.component';

@NgModule({
  declarations: [
    HeaderComponent,
    FooterComponent,
    SidebarComponent
  ],
  imports: [
    CommonModule,
    FormsModule
  ],
  exports: [
    HeaderComponent,
    FooterComponent,
    SidebarComponent,
    CommonModule,
    FormsModule
  ]
})
export class CoreModule { }

Yukarıdaki örnek, bir CoreModule adlı bir modül oluşturur. Bu modül, HeaderComponent, FooterComponent ve SidebarComponent bileşenlerini içerir. Ayrıca, bu modül CommonModule ve FormsModule gibi Angular’ın dahili modüllerini içeri aktarır ve bunları dışa aktararak diğer modüllere kullanımını sağlar.

Angular modüllerin kullanımı, uygulamanızın boyutu ve karmaşıklığına bağlı olarak değişebilir. Küçük uygulamalar için birkaç modül yeterli olabilirken, büyük uygulamalar genellikle birçok modüle ihtiyaç duyar. Modüllerin mantıklı bir şekilde düzenlenmesi ve iyi bir yapılandırılması, Angular uygulamanızın geliştirilmesi, bakımı ve ölçeklendirilmesi açısından kritik öneme sahiptir.

Angular component decorator

Angular’da bileşenler (components), kullanıcı arayüzünün (UI) parçalarını oluşturmanın ana yapı taşlarıdır. Bileşenler, HTML şablonlarını, CSS stillerini ve işlevselliği (JavaScript veya TypeScript kodunu) bir araya getirerek yeniden kullanılabilir, bağımsız ve modüler bir şekilde oluşturulurlar. Bileşenler, Angular uygulamasının temel yapı taşlarından biridir ve genellikle birer UI öğesi olarak düşünülürler.

Angular bileşenlerini tanımlamak için @Component dekoratörü kullanılır. Bu dekoratör, bir bileşenin temel özelliklerini ve davranışlarını belirtmek için kullanılır. Bir bileşen oluşturulurken, @Component dekoratörü ile belirli özellikler sağlanır ve bu özellikler, bileşenin nasıl davranacağını ve nasıl görüneceğini tanımlar.

@Component dekoratörünün bazı yaygın özellikleri şunlardır:

  1. selector: Bileşenin HTML’de kullanılacağı öğenin seçicisidir. Bu, bir bileşenin adını temsil eder ve kullanılabilirliğini sağlar.
  2. template veya templateUrl: Bileşenin görünümünü belirleyen HTML şablonunu içerir. template doğrudan HTML içeriğini içerirken, templateUrl bir dış dosyaya (örneğin .html dosyasına) işaret eder.
  3. style veya styleUrls: Bileşenin stilini belirleyen CSS kodunu içerir. style doğrudan CSS kodunu içerirken, styleUrls bir dizi olarak birden çok stil dosyasına işaret eder.
  4. inputs ve outputs: Bileşenin dışarıdan veri girişi (inputs) ve çıkışı (outputs) tanımlamak için kullanılır.
  5. providers: Bileşen için sağlanacak servisleri belirler.

Örnek bir bileşen tanımı:

import { Component } from '@angular/core';

@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
  styleUrls: ['./example.component.css']
})
export class ExampleComponent {
  // Bileşen içeriği ve işlevselliği buraya yazılır
}

Yukarıdaki örnekte, @Component dekoratörü, ExampleComponent adlı bir bileşen tanımlar. Bu bileşen, app-example adında bir HTML öğesine karşılık gelir. Görünümü example.component.html dosyasından, stil dosyaları ise example.component.css dosyasından alınır.

Angular bileşenleri, uygulamanın farklı parçalarını temsil edebilirler. Örneğin, bir blog uygulamasında bir bileşen bir blog yazısını temsil edebilir ve bu bileşenin içinde yazının başlığı, metni ve yorumları gibi veriler yer alabilir. Bu bileşenler, karmaşık arayüzlerin oluşturulması ve yönetilmesi için kullanışlı bir yapı sağlar.

Angular bileşenlerinin tanımlanması ve kullanılması, uygulamanın yapısını ve performansını belirleyen önemli bir faktördür. Bileşenlerin doğru şekilde tasarlanması ve yönetilmesi, uygulamanın geliştirilmesi ve bakımı için kritik öneme sahiptir.

Angular component classes

Angular bileşen sınıfları (component classes), Angular bileşenlerinin arkasındaki işlevselliği ve veri yönetimini sağlayan TypeScript sınıflarıdır. Bileşen sınıfları, bileşenin davranışını ve özelliklerini tanımlarlar ve bu özellikler, bileşenin nasıl çalışacağını ve nasıl etkileşime gireceğini belirler.

Angular bileşen sınıflarının temel özellikleri şunlardır:

  1. Component Logic (Bileşen Mantığı): Bileşen sınıfları, bileşenin arkasındaki işlevselliği sağlar. Bu, bileşenin veri işleme, kullanıcı etkileşimi ve diğer dinamik davranışlarını yönetir.
  2. Data Binding (Veri Bağlama): Bileşen sınıfları, bileşenin verilerini şablonlarla bağlamak için kullanılır. Bu, bileşenin şablonla nasıl etkileşime gireceğini ve hangi verileri görüntüleyeceğini belirler.
  3. Lifecycle Hooks (Yaşam Döngüsü Hook’ları): Angular bileşen sınıfları, bileşenin yaşam döngüsü boyunca belirli anlarda çağrılan özel yöntemleri içerebilir. Bu yöntemler, bileşenin oluşturulması, güncellenmesi, görüntülenmesi ve yok edilmesi gibi olayları ele almak için kullanılır.
  4. Dependency Injection (Bağımlılık Enjeksiyonu): Bileşen sınıfları, bağımlılık enjeksiyonunu kullanarak hizmetlere erişim sağlarlar. Bu, bileşenlerin dış hizmetlere erişmesini ve bu hizmetler aracılığıyla işlevselliği genişletmesini sağlar.

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
  styleUrls: ['./example.component.css']
})
export class ExampleComponent implements OnInit {
  // Bileşen sınıfı özellikleri
  title: string = 'Example Component';
  itemCount: number = 0;

  // Constructor
  constructor() {
    // Constructor işlemleri
  }

  // OnInit lifecycle hook
  ngOnInit(): void {
    // OnInit işlemleri
    this.itemCount = 10;
  }

  // Özel bir bileşen metodu
  addItem(): void {
    this.itemCount++;
  }

  // Özel bir bileşen metodu
  removeItem(): void {
    this.itemCount--;
  }
}

Yukarıdaki örnekte, ExampleComponent adında bir bileşen sınıfı tanımlanmıştır. Bu sınıf, @Component dekoratörü ile işaretlenir ve selector, templateUrl, styleUrls gibi bileşen özelliklerini belirtir. Ayrıca OnInit lifecycle hook’u uygulanmış ve ngOnInit yöntemi tanımlanmıştır. Bileşen sınıfı içinde title ve itemCount gibi özellikler, bileşenin veri modelini temsil eder. Ayrıca addItem() ve removeItem() gibi özel metotlar, bileşenin davranışını yönetir.

Bileşen sınıfları, Angular uygulamalarının temel yapı taşlarından biridir ve bileşenlerin oluşturulması, yönetilmesi ve kullanılmasında kritik bir rol oynarlar. Doğru şekilde tasarlanmış ve yönetilen bileşen sınıfları, uygulamanın geliştirilmesi ve bakımı açısından büyük öneme sahiptir.

Reference variables and data binding in Angular templates

Angular şablonlarında referans değişkenleri ve veri bağlamaları (data binding), kullanıcı arayüzü (UI) öğelerini dinamik bir şekilde oluşturmanın ve yönetmenin önemli bir yoludur. Referans değişkenleri, şablon içindeki belirli bir öğeye (genellikle bir HTML öğesi veya bir Angular bileşeni) referans almak için kullanılır. Bu referanslar, şablon içindeki öğelere erişim sağlamak ve bu öğelerle etkileşime girmek için kullanılabilir. Veri bağlamaları ise, bileşen sınıfındaki verileri (model) şablondaki HTML öğeleri ile bağlamak için kullanılır, böylece veri değiştikçe arayüz otomatik olarak güncellenir.

Referans Değişkenleri (Template Reference Variables): Angular’da referans değişkenleri, bir HTML öğesine bir ad vererek, bu öğeye şablondan erişim sağlamayı sağlar. Genellikle # sembolü ile başlarlar. Bu referans değişkenleri, öğeler üzerinde işlemler gerçekleştirmek veya verileri almak için kullanılabilir.

<input #myInput type="text">
<button (click)="logInputValue(myInput.value)">Log Value</button>

Yukarıdaki örnekte, #myInput referans değişkeni, <input> öğesine bir referans oluşturur. Ardından, logInputValue() metoduna bu referansın değeri geçirilir.

Veri Bağlamaları (Data Bindings): Angular’da veri bağlamaları, bileşen sınıfındaki verileri (model) HTML şablonundaki öğelerle ilişkilendirir. Bu bağlamalar, değişkenleri şablondaki metin, özellik veya olaylarla ilişkilendirerek verilerin dinamik olarak görüntülenmesini sağlar.

export class AppComponent {
  username: string = 'John Doe';
}
<p>Welcome, {{ username }}!</p>

Yukarıdaki örnekte, {{ username }} ifadesi, username değişkeninin değerini görüntüler. Değişkenin değeri değiştiğinde, arayüz otomatik olarak güncellenir.

Bu iki kavramı birlikte kullanarak, kullanıcıların girdiği değerleri alabilir, bu değerleri işleyebilir ve sonuçları arayüzde görüntüleyebilirsiniz.

Örnek bir uygulama senaryosu:

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
    <input #nameInput type="text" placeholder="Enter your name">
    <button (click)="updateName(nameInput.value)">Update Name</button>
    <p>Welcome, {{ username }}!</p>
  `
})
export class AppComponent {
  username: string = 'John Doe';

  updateName(name: string): void {
    this.username = name;
  }
}

Bu örnekte, kullanıcı bir isim girer ve “Update Name” düğmesine tıkladığında updateName() yöntemi çağrılır ve username değişkeni güncellenir. Şablon içindeki {{ username }} ifadesi, yeni kullanıcı adını otomatik olarak yansıtır. Bu, Angular’da referans değişkenlerini ve veri bağlamalarını kullanarak basit bir veri giriş ve görüntüleme işlemini gerçekleştirir.

Structural directives in Angular templates

Angular şablonlarında yapısal direktifler (structural directives), HTML yapısını dinamik olarak değiştirmek ve işlemek için kullanılan özel direktiflerdir. Yapısal direktifler, şablonun yapısını kontrol etmek için kullanılır ve genellikle * sembolü ile başlarlar. Angular’da en yaygın kullanılan yapısal direktifler şunlardır:

  1. ngIf: Belirli bir koşul doğru olduğunda bir öğeyi ekler veya kaldırır.
  2. ngFor: Belirli bir koleksiyonu (diziyi) döngüsel olarak işler ve her öğe için tekrarlayan bir HTML bloğu oluşturur.
  3. ngSwitch: Belirli bir ifadeye göre farklı HTML bloklarını gösterir veya gizler.
  4. ngTemplateOutlet: Bir şablonu başka bir yerde kullanmak için kullanılır.

Bu yapısal direktifler, Angular uygulamalarında dinamik içerik oluşturmak ve göstermek için güçlü araçlardır.

Örnek kullanımlar:

ngIf:

<div *ngIf="userLoggedIn; else guestTemplate">
  <p>Welcome, {{ username }}!</p>
</div>
<ng-template #guestTemplate>
  <p>Please log in to continue.</p>
</ng-template>

Yukarıdaki örnekte, *ngIf direktifi, userLoggedIn değişkeninin değerine bağlı olarak kullanıcının giriş yapmış olup olmadığını kontrol eder. Eğer kullanıcı giriş yapmışsa, kullanıcı adını görüntüler; aksi halde, “Please log in to continue.” mesajını gösterir.

ngFor:

<ul>
  <li *ngFor="let item of items">{{ item }}</li>
</ul>

Yukarıdaki örnekte, *ngFor direktifi, items dizisindeki her öğe için bir liste öğesi oluşturur ve döngü içinde item değişkeni ile erişilebilir.

ngSwitch:

<div [ngSwitch]="color">
  <p *ngSwitchCase="'red'">Red Color</p>
  <p *ngSwitchCase="'blue'">Blue Color</p>
  <p *ngSwitchDefault>Other Color</p>
</div>

Yukarıdaki örnekte, *ngSwitch direktifi, color değişkeninin değerine göre farklı HTML bloklarını görüntüler. Eğer renk “red” ise “Red Color” mesajını görüntüler, eğer “blue” ise “Blue Color” mesajını görüntüler, aksi halde “Other Color” mesajını görüntüler.

Bu yapısal direktifler, Angular şablonlarında dinamik içerik oluşturmanın ve görüntülemenin önemli bir yoludur. Bu direktifler sayesinde, uygulamanızın kullanıcı arayüzünü dinamik ve etkileşimli bir şekilde oluşturabilir ve yönetebilirsiniz.

Angular standalone components

Angular’da bağımsız bileşenler (standalone components), Angular uygulamanızda tekrar kullanılabilir ve kendi içinde bağımsız çalışabilen bileşenlerdir. Bu bileşenler, genellikle herhangi bir bileşen hiyerarşisine bağlı olmadan tek başına kullanılabilir ve genellikle küçük, özel işlevlere sahip parçaları temsil ederler.

Standalone bileşenlerin avantajları şunlar olabilir:

  1. Yeniden Kullanılabilirlik: Standalone bileşenler, tekrar kullanılabilir yapılar oluşturmak için idealdir. Aynı bileşeni farklı yerlerde birden fazla kez kullanabilirsiniz.
  2. Bağımsızlık: Standalone bileşenler, diğer bileşenlerden bağımsızdır ve kendi içinde tamamen çalışabilirler. Bu, bileşenin kolayca test edilmesini, bakımını yapılmasını ve yeniden kullanılmasını sağlar.
  3. Modülerlik: Standalone bileşenler, uygulamanızı modüler hale getirir ve karmaşık yapıları daha küçük ve yönetilebilir parçalara böler.

Bir Angular bağımsız bileşenini oluşturmak için aşağıdaki adımları izleyebiliriz:

  1. Component Sınıfının Oluşturulması: Bileşenin işlevselliğini ve veri modelini tanımlayan bir TypeScript sınıfı oluşturun.
  2. Component Şablonunun Oluşturulması: Bileşenin görünümünü (HTML yapısını) tanımlayan bir şablon oluşturun.
  3. Component Dekoratörünün Kullanılması: @Component dekoratörü ile bileşenin özelliklerini (selector, template, styleUrls vb.) belirtin.
  4. Modülde Bileşenin Tanımlanması: Bileşeni kullanacağınız modülde tanımlayın veya bir başka modüle ekleyin.

Örnek bir Angular bağımsız bileşeni:

// standalone.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-standalone',
  template: `
    <div>
      <h2>{{ title }}</h2>
      <p>This is a standalone component.</p>
    </div>
  `,
  styleUrls: ['./standalone.component.css']
})
export class StandaloneComponent {
  title: string = 'Standalone Component';
}

Yukarıdaki örnekte, StandaloneComponent adında bir bağımsız bileşen tanımlanmıştır. Bileşenin template’ini ve stil dosyalarını içeren template ve styleUrls özellikleri belirtilmiştir. title adında bir özellik de bileşenin içerisinde tanımlanmıştır.

Bu bağımsız bileşeni bir modüle eklemek için ise şu adımları izleyebiliriz:

// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { StandaloneComponent } from './standalone.component';

@NgModule({
  declarations: [
    StandaloneComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  bootstrap: [StandaloneComponent]
})
export class AppModule { }

Bu şekilde, StandaloneComponent bileşenini kullanacağımız AppModule‘e ekleyerek kullanılabilir hale getirmiş oluruz.

Standalone bileşenler, Angular uygulamalarında modüler yapı oluşturmanın önemli bir parçasıdır ve küçük, yeniden kullanılabilir bileşenler oluşturmak için güçlü bir araçtır. Bu bileşenler sayesinde, uygulamanızı daha kolay yönetebilir ve bakımını yapabilirsiniz.

Common Patterns

Overview of Angular pipes

Angular pipes, veri manipülasyonunu ve şablonlarda görüntülenen verilerin biçimlendirilmesini sağlayan güçlü bir özelliktir. Pipes, Angular’da önemli bir yer tutar ve yaygın olarak kullanılır. Genel olarak, bir pipe, girdi (input) verisini alır, belirli bir işlemi gerçekleştirir ve sonucu döndürür. Örneğin, bir dizeyi büyük harfe dönüştüren uppercase pipe’i veya bir tarihi belirli bir biçime göre biçimlendiren date pipe’i gibi.

Angular’da yaygın olarak kullanılan bazı built-in pipes şunlardır:

  1. DatePipe: Tarihleri biçimlendirmek ve formatlamak için kullanılır.
  2. UpperCasePipe ve LowerCasePipe: Metinleri büyük veya küçük harfe dönüştürmek için kullanılır.
  3. CurrencyPipe: Para birimlerini biçimlendirmek için kullanılır.
  4. DecimalPipe: Ondalık sayıları biçimlendirmek için kullanılır.
  5. PercentPipe: Yüzde değerlerini biçimlendirmek için kullanılır.

Angular, bu tür birçok built-in pipe sağlar ve ayrıca kendi özel pipe’lerinizi de oluşturmanıza izin verir.

Angular pipes’in kullanımı:

Built-in Pipes:

<p>{{ currentDate | date:'shortDate' }}</p>
<p>{{ username | uppercase }}</p>
<p>{{ price | currency:'EUR':'symbol':'1.2-2' }}</p>
<p>{{ quantity | percent }}</p>

Yukarıdaki örnekte, farklı built-in pipes kullanılarak tarihlerin, metinlerin, para birimlerinin ve yüzde değerlerinin nasıl biçimlendirilebileceği gösterilmektedir. Her pipe, belirli bir biçimlendirme veya dönüşüm işlemini gerçekleştirir.

Özel Pipes:

Angular’da kendi özel pipe’lerinizi de oluşturabilirsiniz. Özel bir pipe oluşturmak için, Pipe dekoratörünü kullanarak bir sınıf oluşturmanız ve PipeTransform arayüzünü uygulamanız gerekir. Ardından, transform metodunu uygulayarak pipe’in davranışını tanımlarsınız.

Örnek bir özel pipe:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'customPipe'
})
export class CustomPipe implements PipeTransform {
  transform(value: string): string {
    // Özel dönüşüm işlemleri
    return value.toUpperCase();
  }
}
<p>{{ customText | customPipe }}</p>

Yukarıdaki örnekte, CustomPipe adında bir özel pipe tanımlanmıştır. Bu pipe, gelen metin değerini büyük harfe dönüştürür. Şablon içinde customText değeri bu özel pipe’e geçirilir ve sonuç olarak büyük harfe dönüştürülmüş bir metin elde edilir.

Angular pipes, verileri şablonlarda görüntülemek ve biçimlendirmek için güçlü bir araçtır. Bu, veri görselleştirmesini daha kolay ve esnek hale getirir ve kullanıcıların daha iyi bir deneyim yaşamasını sağlar.

Using built-in Angular pipes

Angular’da bulunan built-in pipes, verileri şablonlarda görüntülemek ve biçimlendirmek için kullanılır. Bu pipes’ler, sıkça kullanılan işlemleri gerçekleştirmek için hazır olarak gelir ve genellikle veri biçimlendirme, dönüştürme veya filtreleme işlemleri için kullanılır.

DatePipe: Tarihleri biçimlendirmek için kullanılır. date pipe’i, bir tarih nesnesini alır ve belirli bir biçimde görüntüler. Kullanımı şu şekildedir:

<p>Today's date is {{ currentDate | date }}</p>

Bu örnekte, currentDate değişkeni bir tarih nesnesi tutuyorsa, bu tarih MM/dd/yyyy biçiminde görüntülenecektir.

UpperCasePipe ve LowerCasePipe: Metinleri büyük veya küçük harfe dönüştürmek için kullanılır. Kullanımları şu şekildedir:

<p>{{ 'Hello World' | uppercase }}</p>
<p>{{ 'HELLO ANGULAR' | lowercase }}</p>

Bu örnekte, metinlerin tümü büyük harfe veya küçük harfe dönüştürülecektir.

CurrencyPipe: Para birimlerini biçimlendirmek için kullanılır. Kullanımı şu şekildedir:

<p>{{ price | currency:'USD':'symbol':'1.2-2' }}</p>

Bu örnekte, price değişkeni bir sayıyı temsil ediyorsa, bu sayı Amerikan Doları (USD) sembolüyle biçimlendirilecek ve virgülden sonra en fazla 2 ondalık basamağa sahip olacak şekilde görüntülenecektir.

DecimalPipe: Ondalık sayıları biçimlendirmek için kullanılır. Kullanımı şu şekildedir:

<p>{{ pi | number:'1.4-4' }}</p>

Bu örnekte, pi değişkeni bir sayıyı temsil ediyorsa, bu sayı en az 1 basamak ve en fazla 4 ondalık basamağa sahip olacak şekilde biçimlendirilecektir.

PercentPipe: Yüzde değerlerini biçimlendirmek için kullanılır. Kullanımı şu şekildedir:

<p>{{ interestRate | percent:'1.2-2' }}</p>

Bu örnekte, interestRate değişkeni bir sayıyı temsil ediyorsa, bu sayı yüzde olarak görüntülenecek ve virgülden sonra en fazla 2 ondalık basamağa sahip olacak şekilde biçimlendirilecektir.

Bu örneklerde gösterilen built-in pipes’ler, Angular’da sıkça kullanılan ve verilerin görüntülenmesini ve biçimlendirilmesini kolaylaştıran önemli araçlardır. Bu pipes’leri kullanarak verileri uygun bir şekilde biçimlendirebilir ve kullanıcı arayüzünde daha anlaşılır bir deneyim sunabilirsiniz.

Using custom Angular pipes

Angular’da özel pipe’ler, kullanıcı tanımlı işlevselliği sağlayan ve şablonlarda veri manipülasyonunu ve biçimlendirmesini gerçekleştiren özel bir yapıdır. Özel pipe’ler, belirli bir işlevi gerçekleştirmek için kullanılan özel işlevleri içerir ve genellikle belirli bir veri türü üzerinde özel bir dönüşüm veya biçimlendirme işlemi yapmak için kullanılır. Özel pipe’ler, PipeTransform arayüzünü uygularlar ve transform metoduyla işlevlerini gerçekleştirirler.

Özel pipe’lerin oluşturulması ve kullanılması için aşağıdaki adımları izleyebilirsiniz:

  1. Pipe Sınıfının Oluşturulması: Bir TypeScript sınıfı oluşturun ve Pipe dekoratörü ile işaretleyin. Bu sınıf, PipeTransform arayüzünü uygulamalıdır.
  2. transform Metodunun Uygulanması: Pipe sınıfında transform metodunu tanımlayın. Bu metod, giriş verisini alır, belirli bir işlemi gerçekleştirir ve sonucu döndürür.
  3. NgModule’de Pipe’in Tanımlanması: Özel pipe’i kullanacağınız modülde veya belirli bir bileşende pipe’i tanımlayın.
  4. Pipe’in Kullanılması: Şablon dosyasında veya bileşen sınıfında özel pipe’i kullanın ve giriş verisini pipe’e aktarın.

Örnek bir özel pipe oluşturmak için:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'customPipe'
})
export class CustomPipe implements PipeTransform {
  transform(value: string): string {
    // Özel dönüşüm işlemleri
    return value.toUpperCase();
  }
}

Yukarıdaki örnekte, CustomPipe adında bir özel pipe tanımlanmıştır. Bu pipe, gelen metin değerini büyük harfe dönüştürür. transform metodunda gerçekleştirilen işlemler, pipe’in işlevselliğini belirler.

Bu özel pipe’i kullanmak için şablon dosyasında veya bileşen sınıfında aşağıdaki gibi kullanabilirsiniz:

<p>{{ customText | customPipe }}</p>

Yukarıdaki örnekte, customText değeri customPipe özel pipe’ine aktarılır ve sonuç olarak büyük harfe dönüştürülmüş bir metin elde edilir.

Özel pipe’ler, Angular uygulamalarında veri manipülasyonu ve biçimlendirme işlemlerini kolaylaştırmak için güçlü bir araçtır. Bu sayede, özel işlevlerinizi oluşturarak tekrar kullanılabilir ve modüler bir şekilde kod yazabilirsiniz.

Angular services and the injectable decorator

Angular servisleri, uygulamanızın farklı bileşenleri arasında veri paylaşımı, iş mantığı yürütme veya dış kaynaklara erişim gibi görevler için kullanılan bir yapıdır. Servisler, bileşenler arasında veri paylaşımını kolaylaştırır ve kodun yeniden kullanılabilirliğini artırır. Angular’da servisler, @Injectable dekoratörü ile işaretlenirler.

Angular servislerinin ana kullanım alanları şunlardır:

Veri Paylaşımı: Servisler, uygulamanın farklı bileşenleri arasında veri paylaşımını sağlarlar. Bileşenler, servise veri gönderebilir veya servisten veri alabilirler.

İş Mantığı Yürütme: Servisler, uygulamanın iş mantığını yönetmek için kullanılır. Örneğin, kullanıcı oturumunu yönetmek, HTTP isteklerini işlemek veya veritabanı işlemlerini gerçekleştirmek için servisler kullanılabilir.

Dış Kaynak Erişimi: Servisler, dış API’lerle veya diğer harici kaynaklarla etkileşimde bulunmak için kullanılabilirler. Bu, HTTP servisleri kullanılarak gerçekleştirilebilir.

Angular’da bir servis oluşturmak için aşağıdaki adımları izleyebilirsiniz:

Servis Sınıfının Oluşturulması: Bir TypeScript sınıfı oluşturun ve @Injectable dekoratörü ile işaretleyin.

İşlevselliğin Tanımlanması: Servis sınıfında uygulanacak işlevselliği tanımlayın. Örneğin, veri işleme, API çağrıları veya iş mantığı işlemleri gibi.

NgModule’de Servisin Tanımlanması: Servisi kullanacağınız modülde veya başka bir yerde servisi tanımlayın. Angular, servisleri sağlamak ve enjekte etmek için providers özelliğini kullanır.

Örnek bir Angular servisi:

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class DataService {
  private data: any[] = [];

  constructor() { }

  setData(data: any[]): void {
    this.data = data;
  }

  getData(): any[] {
    return this.data;
  }
}

Yukarıdaki örnekte, DataService adında bir Angular servisi tanımlanmıştır. Servis, @Injectable dekoratörü ile işaretlenmiş ve providedIn özelliği root olarak ayarlanmıştır, bu da servisin uygulamanın kök modülünde sağlanacağını belirtir. Servis sınıfında setData() ve getData() gibi yöntemler tanımlanmıştır, bu yöntemler servisin içindeki veriye erişmek ve onu güncellemek için kullanılır.

Servisler, bileşenler arasında veri paylaşımını sağlamanın yanı sıra, kodunuzun daha modüler ve yeniden kullanılabilir olmasını sağlar. Ayrıca, servisler, Angular uygulamanızın çeşitli bileşenleri arasında bağımlılıkları azaltarak, uygulamanızın daha iyi bir şekilde organize edilmesine yardımcı olur.

Angular service classes

Angular’da servis sınıfları, uygulama içinde kullanılacak iş mantığını barındıran ve genellikle birden fazla bileşen arasında paylaşılacak olan yapıları temsil eder. Servis sınıfları, belirli bir işlevselliği gerçekleştiren metotlar içerebilir ve bileşenler tarafından enjekte edilerek kullanılabilir. Angular’da servisler genellikle @Injectable dekoratörü ile işaretlenir ve genellikle kök modülde veya belirli bir modülde sağlanır.

Servis sınıflarının kullanım alanları şunlardır:

Veri İşleme ve Paylaşımı: Servisler, uygulama içindeki veri işleme işlevlerini gerçekleştirebilir ve bu verileri bileşenler arasında paylaşabilir.

Harici Kaynak Erişimi: Servisler, harici kaynaklarla (API’ler, veritabanları vb.) etkileşimde bulunmak için kullanılabilirler. Örneğin, HTTP servisleri, AJAX çağrıları yapmak için kullanılabilir.

İş Mantığı Yürütme: Servisler, uygulama içindeki iş mantığını yönetmek için kullanılabilirler. Örneğin, kullanıcı oturumunu yönetmek veya veri doğrulama işlemleri gerçekleştirmek için servisler kullanılabilir.

Servis sınıfları oluştururken dikkat edilmesi gereken bazı noktalar vardır:

  • Servis sınıflarının temiz, modüler ve yeniden kullanılabilir olması gerekir.
  • Her bir servis sınıfının tek bir sorumluluğu olmalıdır.
  • Servis sınıfları, bileşenler tarafından kullanılabilecek şekilde tasarlanmalı ve enjekte edilmelidir.

Örnek bir Angular servis sınıfı:

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class DataService {
  private data: any[] = [];

  constructor() { }

  setData(data: any[]): void {
    this.data = data;
  }

  getData(): any[] {
    return this.data;
  }
}

Yukarıdaki örnekte, DataService adında bir Angular servis sınıfı tanımlanmıştır. Servis, @Injectable dekoratörü ile işaretlenmiş ve providedIn özelliği root olarak ayarlanmıştır, bu da servisin uygulamanın kök modülünde sağlanacağını belirtir. Servis sınıfında setData() ve getData() gibi yöntemler tanımlanmıştır, bu yöntemler servisin içindeki veriye erişmek ve onu güncellemek için kullanılır.

Servis sınıfları, uygulamanızın işlevselliğini modüler ve düzenli bir şekilde düzenlemenize olanak tanır. Bileşenleriniz arasında veri paylaşımını sağlar ve kodunuzu daha kolay bakım yapılabilir hale getirir.

Angular directive decorator

Angular’da direktifler (directives), HTML öğelerine ek işlevsellik eklemek ve bunları manipüle etmek için kullanılan bir yapıdır. Angular’da iki tür direktif bulunur: bileşen direktifleri (component directives) ve yapısal direktifler (structural directives).

@Directive Dekoratörü

@Directive dekoratörü, bir sınıfı Angular direktifi olarak işaretler. Bu sınıflar, genellikle bir HTML öğesine özel işlevsellik eklemek için kullanılır. Örneğin, bir HTML öğesine tıklanabilirlik eklemek, bir öğenin arkaplan rengini değiştirmek veya özel bir davranış sağlamak gibi.

Temel Kullanım
import { Directive, ElementRef, HostListener } from '@angular/core';

@Directive({
  selector: '[appCustomDirective]'
})
export class CustomDirective {
  constructor(private elementRef: ElementRef) {}

  @HostListener('mouseenter') onMouseEnter() {
    this.highlight('yellow');
  }

  @HostListener('mouseleave') onMouseLeave() {
    this.highlight(null);
  }

  private highlight(color: string) {
    this.elementRef.nativeElement.style.backgroundColor = color;
  }
}

Yukarıdaki örnekte, @Directive dekoratörü ile CustomDirective adında bir Angular direktifi tanımlanmıştır. selector özelliği, bu direktifin ne zaman kullanılacağını belirler. Bu örnekte, [appCustomDirective] selektörü, bir HTML öğesine bu direktifin uygulanacağını belirtir. elementRef parametresi, direktifin uygulandığı HTML öğesine erişim sağlar. @HostListener dekoratörü, HTML öğesinde belirli bir olayı dinlemek için kullanılır. Bu örnekte, mouseenter ve mouseleave olayları dinlenir ve ilgili işlevler çalıştırılır.

Kullanımı:
<div appCustomDirective>
  Hover over me to highlight!
</div>

Yukarıdaki HTML örneğinde, appCustomDirective direktifi, bir <div> öğesine uygulanır. Bu, <div> üzerine gelindiğinde arka plan renginin sarıya (yellow) dönüşmesini sağlar.

Angular’daki @Directive dekoratörü, HTML öğelerine ek işlevsellik eklemek için kullanışlı bir araçtır. Bu dekoratörü kullanarak, uygulamanızın farklı bileşenlerine özelleştirilmiş davranışlar ekleyebilir ve yeniden kullanılabilir direktifler oluşturabilirsiniz.

Angular directive classes

Angular’da direktif sınıfları, HTML öğelerine özel davranışlar veya işlevsellik eklemek için kullanılan bir yapıdır. Direktif sınıfları, @Directive dekoratörü ile işaretlenir ve genellikle bir Angular bileşeni olmayan, sadece JavaScript işlevselliği sağlayan sınıflardır. Bu sınıflar, bir bileşenin karmaşıklığını azaltmak ve kodu daha modüler hale getirmek için kullanılır.

Angular Directive Classes (Angular Direktif Sınıfları)

Angular’da direktif sınıfları, genellikle aşağıdaki adımları izleyerek oluşturulur:

Sınıfın Oluşturulması: Direktifin işlevselliğini sağlayacak bir TypeScript sınıfı oluşturulur.

@Directive Dekoratörü ile İşaretlenmesi: Sınıf, @Directive dekoratörü ile işaretlenir ve gerekli ayarlar sağlanır.

HostListener veya HostBinding Kullanımı (Opsiyonel): Sınıf içindeki metodlar veya özellikler aracılığıyla, HTML öğelerinin olaylarını dinlemek veya özelliklerini değiştirmek için @HostListener veya @HostBinding gibi dekoratörler kullanılabilir.

Selector Belirlenmesi: selector özelliği, direktifin ne zaman uygulanacağını belirler. Bu, bir HTML öğesinin adı, sınıfı veya öznitelikleri olabilir.

Örnek bir direktif sınıfı oluşturalım:

import { Directive, HostListener, ElementRef } from '@angular/core';

@Directive({
  selector: '[appCustomDirective]'
})
export class CustomDirective {
  constructor(private elementRef: ElementRef) {}

  @HostListener('mouseenter') onMouseEnter() {
    this.highlight('yellow');
  }

  @HostListener('mouseleave') onMouseLeave() {
    this.highlight(null);
  }

  private highlight(color: string) {
    this.elementRef.nativeElement.style.backgroundColor = color;
  }
}

Yukarıdaki örnekte, CustomDirective adında bir direktif sınıfı tanımlanmıştır. Bu sınıf, @Directive dekoratörü ile işaretlenmiş ve [appCustomDirective] selektörü ile ilişkilendirilmiştir. @HostListener dekoratörü, direktifin uygulandığı HTML öğesinde belirli olayları dinlemek için kullanılmıştır. Bu örnekte, fare öğenin üzerine gelindiğinde (mouseenter) ve öğenin üzerinden çıkıldığında (mouseleave) ilgili metotlar tetiklenir ve arka plan rengi değişir.

Bu direktif sınıfını bir HTML öğesine uygulamak için:

<div appCustomDirective>
  Hover over me to highlight!
</div>

Yukarıdaki örnekte, <div> öğesine appCustomDirective direktifi uygulanmıştır. Bu, öğenin üzerine gelindiğinde arka plan renginin sarıya (yellow) dönüşmesini sağlar.

Angular direktif sınıfları, HTML öğelerine özelleştirilmiş işlevsellikler eklemek için güçlü bir araçtır. Bu sınıfları kullanarak, uygulamanızın farklı bileşenlerine özel davranışlar ekleyebilir ve kodunuzu daha modüler ve yeniden kullanılabilir hale getirebilirsiniz.

Coding Essentials

Angular project configuration

Angular projelerinin yapılandırılması, projenin başlatılması, yapılandırılması ve yönetilmesi için gereken temel adımları içerir. Angular CLI (Command Line Interface) genellikle yeni bir Angular projesi oluştururken kullanılır ve projenin temel yapılandırmasını otomatik olarak sağlar. Ancak, bir Angular projesini manuel olarak yapılandırmak veya yapılandırma dosyalarını özelleştirmek gerekebilir.

Angular Proje Yapılandırması

Angular projeleri, genellikle aşağıdaki temel dosyalardan oluşur:

angular.json: Angular CLI tarafından kullanılan yapılandırma dosyasıdır. Bu dosya, proje yapısını, yapılandırma ayarlarını ve derleme seçeneklerini içerir.

package.json: Proje bağımlılıklarını ve betiklerini yöneten npm (Node Package Manager) yapılandırma dosyasıdır.

tsconfig.json: TypeScript derleme seçeneklerini ve yapılandırmalarını içeren dosyadır.

tslint.json (opsiyonel): TypeScript kodunun stil ve kalite kurallarını belirleyen TSLint yapılandırma dosyasıdır.

src/: Projenin kaynak dosyalarını içeren klasördür. Bileşenler, servisler, yönlendiriciler ve diğer kodlar burada bulunur.

src/index.html: Ana HTML dosyasıdır. Angular uygulaması, bu dosyayı temel bir yapı olarak kullanır.

src/main.ts: Ana TypeScript dosyasıdır. Angular uygulamasının başlatıldığı ve platformun yüklendiği yerdir.

src/app/: Angular uygulamasının temel bileşenlerini, hizmetlerini ve diğer kodlarını içeren klasördür.

Angular projeleri genellikle Angular CLI aracılığıyla oluşturulur. Örneğin, yeni bir Angular projesi oluşturmak için terminalde şu komutu kullanabilirsiniz:

ng new my-app

Bu komut, my-app adında yeni bir Angular projesi oluşturur. Oluşturulan proje, yukarıda belirtilen temel dosyaları ve klasörleri içerir. Daha sonra, oluşturulan projeyi bir kod editöründe açarak ve bu dosyaları inceleyerek projeyi daha fazla özelleştirebilirsiniz.

Angular projelerinin yapılandırılması ve dosyalarının anlaşılması, projenin başarıyla geliştirilmesi ve yönetilmesi için önemlidir. Bu dosyalar, proje yapılandırmasını ve derleme seçeneklerini belirlerken, src/ klasörü ise proje kodlarını içerir. Bu temel yapıyı anlamak, Angular projelerinin daha etkili bir şekilde geliştirilmesine yardımcı olabilir.

Application environments and build targets

Angular’da uygulama ortamları (application environments) ve derleme hedefleri (build targets), farklı ortamlarda ve hedeflerde uygulamanızı nasıl yapılandıracağınızı ve derleyeceğinizi belirlemenize olanak tanır. Bu, geliştirme, test, üretim gibi farklı ortamlar için farklı yapılandırmaların kullanılması anlamına gelir. Angular CLI, bu tür farklı ortamlar ve hedefler için yapılandırma ve derleme seçeneklerini kolayca yönetmenize olanak tanır.

Application Environments (Uygulama Ortamları)

Angular’da uygulama ortamları, uygulamanızın çalıştığı çevreyi belirler. Örneğin, geliştirme, test ve üretim gibi farklı ortamlar, farklı yapılandırma seçenekleri gerektirebilir. Angular’da, varsayılan olarak üç temel uygulama ortamı vardır:

  1. development: Geliştirme ortamı için yapılandırma.
  2. production: Üretim ortamı için yapılandırma.
  3. test: Test ortamı için yapılandırma.

Bu ortamlar, varsayılan olarak src/environments/ dizininde bulunan dosyalar aracılığıyla yapılandırılır. Örneğin, environment.ts (development), environment.prod.ts (production) ve environment.test.ts (test) gibi.

Build Targets (Derleme Hedefleri)

Angular’da derleme hedefleri, uygulamanın farklı ortamlar ve platformlar için nasıl derlendiğini belirler. Angular CLI, farklı hedefler için farklı yapılandırma dosyaları kullanarak uygulamanın derlenmesini sağlar. Varsayılan olarak, Angular’da iki temel derleme hedefi bulunur:

  1. development: Geliştirme ortamı için derleme.
  2. production: Üretim ortamı için derleme.

Bu hedefler, ng build komutuyla kullanılabilir ve --configuration (veya kısa haliyle -c) bayrağı ile belirtilebilir. Örneğin:

ng build --configuration=production

Bu komut, uygulamayı üretim ortamı için derler.

Angular’daki uygulama ortamları ve derleme hedefleri, Angular CLI aracılığıyla kolayca yapılandırılabilir ve yönetilebilir. Örneğin, farklı ortamlar için farklı yapılandırma dosyaları kullanarak ortam değişkenlerini ayarlayabilir veya farklı derleme seçenekleri ekleyebilirsiniz. Bu, uygulamanızı farklı ortamlarda ve hedeflerde başarılı bir şekilde çalıştırmak için önemli bir araçtır.

Aşağıda, Angular’da varsayılan olarak bulunan environment.ts dosyasının bir örneği bulunmaktadır:

// environment.ts
export const environment = {
  production: false,
  apiUrl: 'https://api.example.com'
};

Bu dosya, production özelliğini false olarak ve bir API URL’sini içerir. environment.prod.ts dosyası ise production özelliğini true olarak ayarlayarak, üretim ortamı için farklı bir yapılandırma sağlayabilir. Bu yapılandırmalar, uygulama kodunuz içinde bu ortamlara özgü davranışlar sağlamak için kullanılabilir.

Injecting dependencies using dependency injection

Angular’da bağımlılıkların enjekte edilmesi, Dependency Injection (Bağımlılık Enjeksiyonu) prensibine dayanır. Bu prensip, bileşenlerin ve diğer sınıfların gereksinim duyduğu başka sınıfları veya hizmetleri almasını sağlar. Angular, bu prensibi kullanarak bileşenler arasında veri paylaşımını, servis kullanımını ve kodun daha modüler hale getirilmesini sağlar.

Dependency Injection (Bağımlılık Enjeksiyonu) Nasıl Çalışır?

Angular, bileşenlerin ve diğer sınıfların bağımlılıklarını (dependencies) bileşen oluşturulurken sağlar. Bu bağımlılıklar, genellikle bir servis, bir başka bileşen veya bir değer olabilir. Bağımlılıkların enjekte edilmesi, Angular’in sağladığı bir yapılandırma mekanizması aracılığıyla gerçekleşir.

Bağımlılıkların enjekte edilmesi için genellikle şu adımlar izlenir:

Bağımlılığın Tanımlanması: Bağımlılığın, bir sınıfın constructor (yapıcı) metodunda parametre olarak belirtilmesiyle tanımlanır.

Angular Tarafından Enjeksiyon: Angular, bileşenin oluşturulması sırasında bu bağımlılığı algılar ve gerektiğinde sağlar.

Bağımlılığın Kullanımı: Bağımlılık, bileşen veya sınıf içinde kullanılabilir hale gelir ve gerektiğinde çağrılabilir.

Dependency Injection ile Örnek

Örnek olarak, bir servisin bir bileşene nasıl enjekte edileceğini gösteren bir Angular bileşeni:

import { Component } from '@angular/core';
import { DataService } from './data.service'; // Servisimizi içe aktarıyoruz

@Component({
  selector: 'app-root',
  template: `
    <h1>{{ message }}</h1>
  `,
  providers: [DataService] // Servisimizi bileşenimize sağlıyoruz
})
export class AppComponent {
  message: string;

  constructor(private dataService: DataService) {
    this.message = this.dataService.getMessage(); // Servisimizi kullanıyoruz
  }
}

Yukarıdaki örnekte, AppComponent adında bir Angular bileşeni tanımlanmıştır. Bu bileşen, DataService adlı bir servisi kullanmaktadır. Bağımlılık enjeksiyonu, AppComponent bileşeninin constructor (yapıcı) metodunda DataService parametresi olarak tanımlanarak gerçekleşir. Angular, DataService‘i AppComponent oluşturulurken otomatik olarak sağlar.

Servis sınıfı DataService şu şekilde tanımlanabilir:

import { Injectable } from '@angular/core';

@Injectable()
export class DataService {
  getMessage(): string {
    return 'Hello from DataService!';
  }
}

Yukarıdaki örnekte, DataService adında bir Angular servisi tanımlanmıştır. Bu servis, bileşenlere bir mesaj döndüren getMessage() yöntemini sağlar. @Injectable() dekoratörü, bu sınıfın bir Angular servisi olduğunu belirtir.

Dependency Injection, Angular’da kodun daha modüler hale getirilmesini ve bileşenler arasında veri paylaşımını kolaylaştırır. Bağımlılıkların enjekte edilmesi, kodun daha okunabilir ve bakımı daha kolay hale gelmesine katkıda bulunur.

Declaring dependencies using dependency injection

Angular’da bağımlılıkların beyan edilmesi ve Dependency Injection (Bağımlılık Enjeksiyonu) kullanımı, bileşenlerin veya diğer sınıfların gereksinim duyduğu servislerin, diğer bileşenlerin veya değerlerin belirtilmesini içerir. Bu, Angular’in bileşenler arası iletişimi sağlamak ve kodun daha modüler hale getirilmesini desteklemek için kullandığı önemli bir konsepttir.

Bağımlılıkların Beyan Edilmesi

Angular’da, bir bileşen veya bir servis, diğer bağımlılıklarını kullanabilmek için bu bağımlılıkları bileşenin constructor (yapıcı) metodunda tanımlar. Bağımlılıklar genellikle constructor parametreleri olarak tanımlanır ve Angular, bileşenin oluşturulması sırasında bu bağımlılıkları sağlar.

Örnek bir bileşenin bağımlılıklarının beyan edilmesi:

import { Component } from '@angular/core';
import { DataService } from './data.service'; // Servisimizi içe aktarıyoruz

@Component({
  selector: 'app-root',
  template: `
    <h1>{{ message }}</h1>
  `
})
export class AppComponent {
  message: string;

  constructor(private dataService: DataService) { // Bağımlılıkların beyan edilmesi
    this.message = this.dataService.getMessage(); // Bağımlılıkların kullanımı
  }
}

Yukarıdaki örnekte, AppComponent adında bir Angular bileşeni tanımlanmıştır. Bu bileşen, DataService adlı bir servisi kullanmaktadır. Bağımlılıkların beyan edilmesi, AppComponent bileşeninin constructor (yapıcı) metodunda DataService parametresi olarak tanımlanarak gerçekleşir.

Dependency Injection (Bağımlılık Enjeksiyonu) Kullanımı

Angular, bileşenlerin ve diğer sınıfların bağımlılıklarını sağlamak için Dependency Injection (Bağımlılık Enjeksiyonu) yöntemini kullanır. Bu yöntem, bağımlılıkların bileşen oluşturulurken sağlanmasını sağlar. Angular, bileşenin oluşturulması sırasında constructor metodu aracılığıyla bağımlılıkları algılar ve gerektiğinde sağlar.

Örnek olarak, yukarıdaki AppComponent bileşeni, DataService servisini kullanmak için Dependency Injection kullanır. Bu, AppComponent bileşeni oluşturulduğunda DataService servisinin otomatik olarak sağlanmasını sağlar ve AppComponent bileşeni içinde bu servise erişim sağlanır.

Bağımlılıkların beyan edilmesi ve Dependency Injection kullanımı, Angular’da kodun daha modüler ve yeniden kullanılabilir hale getirilmesine olanak tanır. Bu, bileşenler arasındaki iletişimi kolaylaştırır ve kodun daha okunabilir ve bakımı daha kolay hale gelmesine katkıda bulunur.

Providing dependencies using dependency injection

Angular’da, Dependency Injection (Bağımlılık Enjeksiyonu) kullanılarak bağımlılıkların sağlanması, Angular uygulamalarında önemli bir konudur. Bağımlılıkların sağlanması, Angular’ın bileşenler arasındaki iletişimi kolaylaştıran ve kodun daha modüler hale getirilmesini sağlayan bir mekanizmadır.

Bağımlılıkların Sağlanması (Providing Dependencies)

Angular’da, bağımlılıkların sağlanması, genellikle bir servis veya başka bir bileşenin sağlanmasıyla gerçekleşir. Bağımlılıklar, @Injectable dekoratörüyle işaretlenmiş servisler veya bileşen sınıfları olarak sağlanabilir.

Servislerin Sağlanması

Angular’da bir servis, @Injectable dekoratörü ile işaretlenir ve providedIn özelliği belirtilerek sağlanır. Servisler, genellikle uygulamanın kök modülünde veya belirli bir modülde sağlanır.

Örnek bir servisin sağlanması:

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class DataService {
  // Servisin işlevselliği buraya gelir
}

Yukarıdaki örnekte, DataService adında bir Angular servisi tanımlanmıştır. @Injectable dekoratörü ile işaretlenmiş ve providedIn özelliği root olarak ayarlanmıştır, bu da servisin uygulamanın kök modülünde sağlanacağını belirtir.

Bileşenlerin Sağlanması

Bir bileşen, Angular tarafından sağlanır ve kullanılacak bileşenin @Component dekoratörü ile işaretlenmesi yeterlidir. Angular, bileşenin kullanılacağı yerde gerekli bağımlılığı otomatik olarak sağlar.

Örnek bir bileşenin sağlanması:

import { Component } from '@angular/core';

@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
  styleUrls: ['./example.component.css']
})
export class ExampleComponent {
  // Bileşen kodu buraya gelir
}

Yukarıdaki örnekte, ExampleComponent adında bir Angular bileşeni tanımlanmıştır. Bu bileşen, @Component dekoratörü ile işaretlenmiştir.

Dependency Injection Kullanımı

Bağımlılıklar, Angular tarafından bileşenler oluşturulurken otomatik olarak enjekte edilir. Bu, bileşenin constructor (yapıcı) metodu aracılığıyla gerçekleşir. Bağımlılıkların, bileşenin constructor parametreleri olarak tanımlanması ve Angular’in bu parametreleri bileşenin oluşturulması sırasında sağlaması şeklinde çalışır.

Örnek bir bileşenin bağımlılıklarının kullanımı:

import { Component } from '@angular/core';
import { DataService } from './data.service';

@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
  styleUrls: ['./example.component.css']
})
export class ExampleComponent {
  constructor(private dataService: DataService) {
    // Bağımlılıkların kullanımı
  }
}

Yukarıdaki örnekte, ExampleComponent bileşeni, DataService adlı bir servisi kullanır. Bağımlılık enjeksiyonu, ExampleComponent bileşenin oluşturulması sırasında DataService servisini otomatik olarak sağlar.

Bağımlılıkların sağlanması ve Dependency Injection kullanımı, Angular uygulamalarında bileşenler arasında iletişimi sağlamanın temel bir yoludur. Bu, kodun daha modüler hale getirilmesine ve bileşenlerin yeniden kullanılabilirliğinin artırılmasına yardımcı olur.

Angular change detection strategies

Angular’da değişiklik algılama stratejileri, Angular uygulamalarında performansı optimize etmek için kullanılan önemli bir konsepttir. Değişiklik algılama stratejileri, Angular’ın bileşenlerdeki değişiklikleri algılama ve bileşen ağacını güncelleme şeklini belirler. Bu stratejiler, uygulamanın performansını etkileyebilir ve gereksiz yeniden işlemelerin önlenmesine yardımcı olabilir.

Değişiklik Algılama Stratejileri

Angular’da iki temel değişiklik algılama stratejisi bulunmaktadır:

Default (Varsayılan) Change Detection: Bu strateji, tüm bileşenler ve bileşen ağacı üzerinde herhangi bir değişiklik olduğunda, tüm bileşenlerin ve alt bileşenlerin yeniden işlenmesini tetikler.

OnPush Change Detection: Bu strateji, sadece bir bileşenin giriş bağlantılarından veya referanslarından bir değişiklik algılandığında, ilgili bileşen ve alt bileşenlerinin yeniden işlenmesini tetikler. Diğer bir deyişle, sadece giriş bağlantıları veya referansları değiştiğinde yeniden işleme başvurulur.

OnPush Change Detection Stratejisi Kullanımı

OnPush değişiklik algılama stratejisinin kullanımı, bileşenlerin ChangeDetectionStrategy.OnPush ile işaretlenmesiyle sağlanır. Bu strateji, bileşen sınıfının üstüne @Component dekoratörü altında belirtilir.

Örnek bir bileşenin OnPush değişiklik algılama stratejisi ile işaretlenmesi:

import { Component, ChangeDetectionStrategy } from '@angular/core';

@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
  styleUrls: ['./example.component.css'],
  changeDetection: ChangeDetectionStrategy.OnPush // OnPush değişiklik algılama stratejisi
})
export class ExampleComponent {
  // Bileşen kodu buraya gelir
}

Yukarıdaki örnekte, ExampleComponent adında bir Angular bileşeni tanımlanmıştır. @Component dekoratörü altında, changeDetection özelliği ChangeDetectionStrategy.OnPush olarak ayarlanmıştır. Bu, bileşenin OnPush değişiklik algılama stratejisi ile işaretlendiğini belirtir.

OnPush Change Detection Stratejisinin Avantajları
  • Performans: OnPush stratejisi, gereksiz yeniden işlemelerin önlenmesine yardımcı olabilir, çünkü sadece belirli koşullar sağlandığında yeniden işleme başvurulur.
  • Bellek Kullanımı: Bu strateji, gereksiz bellek tüketimini azaltabilir, çünkü sadece değişen bileşenlerin ve alt bileşenlerin yeniden işlenmesini gerektirir.

OnPush değişiklik algılama stratejisi, Angular uygulamalarının performansını artırmak için güçlü bir araçtır. Doğru kullanıldığında, uygulamanın tepki verme süresini iyileştirebilir ve kaynak kullanımını azaltabilir. Ancak, dikkatli bir şekilde kullanılmalıdır, çünkü yanlış kullanımı beklenmeyen davranışlara neden olabilir. Bu nedenle, OnPush stratejisinin sadece gerekli durumlarda ve doğru bir şekilde kullanılması önemlidir.

Angular component lifecycle hooks

Angular bileşenlerinin yaşam döngüsü kancaları (lifecycle hooks), bileşenlerin oluşturulması, güncellenmesi ve yok edilmesi gibi farklı yaşam döngüsü olayları sırasında çalıştırılan özel yöntemlerdir. Bu kancalar, bileşenlerin farklı aşamalarında özel işlemler gerçekleştirmek için kullanılır. Angular, bileşenlerin bu yaşam döngüsü olayları sırasında otomatik olarak bu kancaları çağırır ve bu sayede bileşenlerin davranışlarını kontrol etmek mümkün olur.

Angular’da yaygın olarak kullanılan bazı yaşam döngüsü kancaları şunlardır:

ngOnInit: Bileşen oluşturulduktan hemen sonra çağrılır. Bileşenin başlangıç durumunu ayarlamak veya veri yükleme işlemlerini gerçekleştirmek için sıklıkla kullanılır.

ngOnChanges: Bileşenin giriş bağlantılarından biri değiştiğinde çağrılır. Değişiklik algılama stratejisi OnPush olarak ayarlandığında, sadece giriş bağlantıları değiştiğinde bu yöntem çağrılır.

ngDoCheck: Angular değişiklik algılama mekanizması tarafından her değişiklik algılandığında çağrılır. Genellikle özel durumlar için kullanılır.

ngAfterContentInit: Bileşenin içerik projeksiyonu (content projection) tamamlandıktan sonra çağrılır. Özellikle ng-content kullanıldığında içerik projeksiyonunu işlemek için kullanılır.

ngAfterContentChecked: Bileşenin içerik projeksiyonu her güncellendiğinde çağrılır. Özellikle içerik projeksiyonu sonrası işlemler için kullanılır.

ngAfterViewInit: Bileşenin görünümleri ve çocuk bileşenleri oluşturulduktan sonra çağrılır. DOM ile ilgili işlemler için kullanılır.

ngAfterViewChecked: Bileşenin görünümleri ve çocuk bileşenleri her güncellendiğinde çağrılır. DOM ile ilgili işlemler sonrası için kullanılır.

ngOnDestroy: Bileşen yok edilmeden hemen önce çağrılır. Bileşenin kaynaklarını serbest bırakmak veya abonelikleri iptal etmek gibi temizleme işlemleri için kullanılır.

Bu yaşam döngüsü kancaları, Angular bileşenlerinin farklı aşamalarında özel işlemler gerçekleştirmek için kullanılır. Örneğin, veri yükleme işlemleri, aboneliklerin başlatılması veya iptal edilmesi, DOM işlemleri ve daha fazlası bu kancalar aracılığıyla yönetilebilir.

Örnek bir Angular bileşeninin yaşam döngüsü kancalarının kullanımı:

import { Component, OnInit, OnDestroy } from '@angular/core';

@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
  styleUrls: ['./example.component.css']
})
export class ExampleComponent implements OnInit, OnDestroy {
  constructor() {
    console.log('Constructor called');
  }

  ngOnInit() {
    console.log('ngOnInit called');
  }

  ngOnDestroy() {
    console.log('ngOnDestroy called');
  }
}

Yukarıdaki örnekte, ExampleComponent adında bir Angular bileşeni tanımlanmıştır. OnInit ve OnDestroy yaşam döngüsü kancaları implements anahtar kelimesi ile bileşen sınıfına dahil edilmiştir. Bu kancalar, bileşenin oluşturulması ve yok edilmesi sırasında özel işlemleri gerçekleştirmek için kullanılır.

Routing and Navigation

Defining routes for Angular Router

Angular’da yönlendirme ve navigasyon, Angular Router kullanılarak yönetilir. Yönlendirme ve navigasyon, kullanıcıların farklı bileşenler arasında geçiş yapmasını ve uygulama içindeki farklı sayfalar arasında gezinmesini sağlar. Angular Router, uygulama rotalarını tanımlamak ve yönetmek için kullanılan bir modüldür.

Rotaların Tanımlanması

Angular’da rotaları tanımlamak için RouterModule kullanılır. RouterModule, uygulama rotalarını belirlemek ve bu rotaları yönetmek için gerekli olan tüm işlevselliği sağlar. Rotalar, genellikle uygulamanın kök modülünde veya ayrı bir rota modülünde tanımlanır.

İşte Angular’da rota tanımlama sürecinin temel adımları:

Rota Tanımlama: Rotanın URL’si ve eşleştiği bileşen belirtilerek bir rota tanımlanır.

Rotanın Yönlendirilmesi: Belirli bir URL’e erişildiğinde, bu URL ile ilişkilendirilmiş bileşenin yüklenmesi sağlanır.

Rotanın Koruması: Belirli bir rota erişimini denetlemek veya izin verilen kullanıcıları kontrol etmek için koruma stratejileri tanımlanabilir.

İşte bir Angular uygulamasında rota tanımlamanın temel bir örneği:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home.component';
import { AboutComponent } from './about.component';
import { ContactComponent } from './contact.component';

const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'about', component: AboutComponent },
  { path: 'contact', component: ContactComponent }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Yukarıdaki örnekte, AppRoutingModule adında bir Angular modülü tanımlanmıştır. RouterModule.forRoot() metodu, rotaları tanımlamak için kullanılır ve rotaları yönetmek için gerekli olan tüm işlevselliği sağlar. Tanımlanan rotalar, Routes dizisi içinde belirtilir. Her bir rota nesnesi, path özelliği ile URL’yi ve component özelliği ile eşleştirilen bileşeni belirtir.

Örneğin, path: '' ile belirtilen rota, uygulamanın ana sayfasını temsil eder ve HomeComponent ile ilişkilendirilir. Benzer şekilde, /about ve /contact URL’leri sırasıyla AboutComponent ve ContactComponent bileşenleri ile ilişkilendirilir.

Bu şekilde, AppRoutingModule modülü uygulamanın rotalarını tanımlar ve yönetir. Bu rotalar, RouterModule.forRoot() ile AppModule‘e içe aktarılarak kullanılır.

Angular’da rotaların tanımlanması, uygulamanın farklı bileşenler arasında geçiş yapmasını ve gezinmesini sağlar. Rota tanımlama, RouterModule kullanılarak gerçekleştirilir ve bu sayede Angular Router tarafından rotaların yönetimi sağlanır. Bu, kullanıcıların uygulama içinde farklı sayfalar arasında kolayca gezinmelerini sağlar ve uygulamanın modülerliğini artırır.

Using routes with Angular’s Router module

Angular’da yönlendirme ve navigasyon, Angular Router modülü kullanılarak sağlanır. Bu modül, uygulamanın rotalarını tanımlamak, yönetmek ve kullanıcıların farklı bileşenler arasında geçiş yapmasını sağlamak için kullanılır. Angular Router, karmaşık uygulamaların bileşen tabanlı yapılarını yönetmek için güçlü bir araçtır.

Rotaların Tanımlanması ve Kullanımı

Angular’da rotaları tanımlamak ve kullanmak için aşağıdaki adımları izleyebiliriz:

AppRoutingModule Oluşturma: Rotaların tanımlandığı ve yönetildiği bir modül oluşturun.

Rotaları Tanımlama: AppRoutingModule modülünde, RouterModule.forRoot() metodu kullanarak rotaları tanımlayın. Her bir rota, bir URL ve eşleştirildiği bileşen arasında bir ilişki tanımlar.

RouterLink Kullanımı: HTML şablonlarında, RouterLink direktifi kullanarak belirli bir rotaya yönlendirme yapın.

Router Servisi Kullanımı: TypeScript kodunda, Router servisini enjekte ederek programatik yönlendirme yapın.

İşte bir Angular uygulamasında rotaların tanımlanması ve kullanımına ilişkin temel bir örnek:

// app-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home.component';
import { AboutComponent } from './about.component';
import { ContactComponent } from './contact.component';

const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'about', component: AboutComponent },
  { path: 'contact', component: ContactComponent }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Yukarıdaki örnekte, AppRoutingModule adında bir Angular modülü tanımlanmıştır. RouterModule.forRoot() metodu ile rotalar tanımlanır ve yönetilir. Tanımlanan rotalar, Routes dizisi içinde belirtilir. Her bir rota nesnesi, path özelliği ile URL’yi ve component özelliği ile eşleştirilen bileşeni belirtir.

<!-- app.component.html -->

<nav>
  <a routerLink="/">Home</a>
  <a routerLink="/about">About</a>
  <a routerLink="/contact">Contact</a>
</nav>

<router-outlet></router-outlet>

Yukarıdaki örnekte, HTML şablonunda routerLink direktifi kullanılarak belirli rotalara yönlendirme yapılır. Bu sayede kullanıcılar tıkladıklarında farklı rotalara geçiş yapabilirler. RouterOutlet direktifi, belirli bir rota eşleştiğinde eşleştirilen bileşenin yükleneceği yer olarak kullanılır.

// app.component.ts

import { Component } from '@angular/core';
import { Router } from '@angular/router';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  constructor(private router: Router) {}

  goToAboutPage() {
    this.router.navigate(['/about']);
  }
}

Yukarıdaki örnekte, TypeScript kodunda Router servisi enjekte edilerek programatik yönlendirme yapılır. goToAboutPage() yöntemi, Router servisi kullanılarak /about rotasına yönlendirme yapar.

Bu şekilde, Angular Router modülü ile rotaların tanımlanması ve kullanımı sağlanır. RouterLink direktifi ile HTML şablonlarında, Router servisi ile programatik olarak veya Router servisi ile yönlendirme yapılarak kullanıcılar uygulama içinde gezinti yapabilirler. Bu, uygulamanın kullanıcı dostu ve kullanışlı bir deneyim sunmasını sağlar.

Lazy loading Angular routes

Angular’da “lazy loading”, uygulamanın yalnızca ihtiyaç duyulduğunda belirli bir modülü veya bileşeni yüklemesini sağlayan bir tekniktir. Özellikle büyük ölçekli Angular uygulamalarında kullanılan bu teknik, uygulamanın başlangıç yükünü azaltır ve performansı artırır. Angular Routing ve Navigation konusunda, lazy loading’i kullanarak uygulamanın rotalarını yüklemek, kullanıcıların belirli bir rotaya ihtiyaç duyduğunda ilgili bileşenlerin yüklenmesini sağlar. Bu, uygulamanın başlangıç yükünü azaltır ve ilk etapta sadece gerekli olan bileşenlerin yüklenmesini sağlar.

Lazy Loading Nasıl Çalışır?

Lazy loading, Angular’da modülleri yüklemek için kullanılan bir yöntemdir. Normalde, Angular uygulamaları başlangıçta tüm modülleri ve bileşenleri yükler. Ancak lazy loading kullanılarak, belirli bir modülün yüklenmesi sadece o modüle ihtiyaç duyulduğunda gerçekleşir. Bu, uygulamanın ilk yüklenme süresini kısaltır ve performansı artırır.

Lazy Loading Nasıl Uygulanır?

Angular’da lazy loading, Angular CLI (Command Line Interface) aracılığıyla çok kolay bir şekilde uygulanabilir. İşte bir Angular uygulamasında lazy loading’in nasıl uygulanacağına dair temel adımlar:

Lazy Loadable Module Oluşturma: Yüklemesi geciktirilecek modül için bir Angular modülü oluşturun.

Routing Modülünde Yönlendirme Tanımlama: Ana uygulama modülünde veya başka bir modülde, lazy loadable modülün rotasını tanımlayın ve loadChildren özelliğiyle yüklenmesi gereken modülü belirtin.

Angular CLI ile Derleme Ayarları: Angular CLI ile derleme yapılandırması yaparak, lazy loadable modülün ayrı bir JavaScript dosyası olarak derlenmesini sağlayın.

Örnek Kodlar

Lazy Loadable Module Oluşturma:

// lazy.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { LazyRoutingModule } from './lazy-routing.module';
import { LazyComponent } from './lazy.component';

@NgModule({
  declarations: [LazyComponent],
  imports: [
    CommonModule,
    LazyRoutingModule
  ]
})
export class LazyModule { }

Routing Modülünde Yönlendirme Tanımlama:

// app-routing.module.ts

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  { path: 'lazy', loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule) }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Angular CLI ile Derleme Ayarları:

Angular CLI’da angular.json dosyasında, lazy loadable modülün derlenmesi için ek ayarlar yapılması gerekir. Örneğin, aşağıdaki gibi:

{
  ...
  "projects": {
    "your-project-name": {
      ...
      "architect": {
        "build": {
          ...
          "options": {
            ...
            "lazyModules": [
              "src/app/lazy/lazy.module"
            ]
          }
        }
      }
    }
  }
}

Bu şekilde, lazy loading kullanarak Angular uygulamalarında modüllerin yüklenmesi geciktirilebilir. Bu sayede uygulama başlangıç yükü azalır ve performans artar. Bu yöntem özellikle büyük ölçekli uygulamalarda kullanıldığında oldukça etkilidir.

Dynamic route parameters in Angular routes

Angular’da dinamik rota parametreleri, bir rotaya geçerli bir değer sağladığınızda rotanın farklı bileşenlerle eşleşmesini sağlayan bir tekniktir. Bu, özellikle dinamik içerik oluşturmak veya belirli verilere dayalı olarak farklı bileşenleri yüklemek için çok kullanışlıdır. Dinamik rota parametreleri, URL’nin bir parçası olarak kullanılır ve genellikle dinamik olarak değişen verileri temsil eder.

Dinamik Rota Parametrelerinin Kullanımı

Rota Tanımlama: Angular’da bir rota tanımlarken, dinamik parametreleri : ile başlatırsınız ve parametrenin adını belirtirsiniz.

const routes: Routes = [
  { path: 'users/:id', component: UserDetailComponent }
];

Parametreyi Yakalama: Bileşenin içinde, ActivatedRoute servisi aracılığıyla dinamik parametreleri yakalayabilirsiniz.

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-user-detail',
  templateUrl: './user-detail.component.html',
  styleUrls: ['./user-detail.component.css']
})
export class UserDetailComponent implements OnInit {
  userId: string;

  constructor(private route: ActivatedRoute) { }

  ngOnInit(): void {
    this.route.params.subscribe(params => {
      this.userId = params['id'];
    });
  }
}

HTML Şablonunda Kullanma: Yakalanan parametreyi HTML şablonunda kullanabilirsiniz.

<p>User ID: {{ userId }}</p>

Bu şekilde, belirli bir kullanıcıya ait detayları göstermek üzere tasarlanmış olan UserDetailComponent, dinamik olarak URL’den kullanıcı kimliğini (id) alır ve bu kimliği kullanarak ilgili kullanıcının detaylarını alır.

Birden Fazla Dinamik Parametre Kullanımı

Eğer rotanızda birden fazla dinamik parametre varsa, tanımlamak ve yakalamak için yukarıdaki adımları aynen kullanabilirsiniz.

const routes: Routes = [
  { path: 'products/:category/:id', component: ProductDetailComponent }
];
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-product-detail',
  templateUrl: './product-detail.component.html',
  styleUrls: ['./product-detail.component.css']
})
export class ProductDetailComponent implements OnInit {
  category: string;
  productId: string;

  constructor(private route: ActivatedRoute) { }

  ngOnInit(): void {
    this.route.params.subscribe(params => {
      this.category = params['category'];
      this.productId = params['id'];
    });
  }
}
<p>Category: {{ category }}</p>
<p>Product ID: {{ productId }}</p>

Bu örnekte, /products/:category/:id rotası, ProductDetailComponent ile eşleştirilir ve URL’den kategori ve ürün kimliğini alarak ilgili ürünün detaylarını alır.

Dinamik rota parametreleri, Angular uygulamalarında farklı bileşenlerin yüklenmesi veya farklı verilerin görüntülenmesi için güçlü bir araçtır. Bu teknik, uygulamanızın esnekliğini artırır ve kullanıcı deneyimini geliştirebilir.

Preloading strategies for Angular Router

Angular’da Angular Router’ın ön yükleme stratejileri, kullanıcıların rotalara hızlı bir şekilde erişim sağlamalarını ve uygulamanın performansını artırmak için kullanılır. Ön yükleme stratejileri, rotaların bileşenlerini önceden yüklemeyi ve arka planda çalışırken kullanıcı rotalarda gezinirken bile gerekli bileşenlerin yüklü olmasını sağlamayı amaçlar.

Angular Router’da varsayılan olarak ön yükleme yapılmaz. Bunun yerine, kullanıcı bir rotaya geçtiğinde ilgili bileşenler yüklenir. Ancak, büyük ve karmaşık uygulamalarda bu durum performans sorunlarına yol açabilir. Bu nedenle, ön yükleme stratejileri kullanarak rotaların bileşenlerini önceden yüklemek, uygulamanın performansını artırabilir.

Angular Router’da kullanılan ön yükleme stratejileri şunlardır:

No Preloading: Bu, rotaların bileşenlerinin sadece talep edildiğinde yüklenmesi anlamına gelir. Bu, varsayılan davranıştır.

Preloading All Modules: Bu strateji, uygulamanın başlangıcında tüm rotaların bileşenlerini ön yükler. Bu, uygulamanın başlangıç yükünü artırabilir ancak kullanıcı rotalara hızlı bir şekilde erişebilir.

Custom Preloading: Bu strateji, belirli rotaların bileşenlerini ön yüklemek için özelleştirilmiş bir yaklaşım sunar. Örneğin, kritik rotaların bileşenlerini önceden yüklemek için kullanılabilir.

Ön yükleme stratejilerini belirlemek için Angular’da PreloadAllModules veya PreloadingStrategy arayüzünü kullanabiliriz.

İşte bir örnek:

import { NgModule } from '@angular/core';
import { RouterModule, Routes, PreloadAllModules } from '@angular/router';

const routes: Routes = [
  { path: 'home', loadChildren: () => import('./home/home.module').then(m => m.HomeModule) },
  { path: 'about', loadChildren: () => import('./about/about.module').then(m => m.AboutModule) },
  { path: 'contact', loadChildren: () => import('./contact/contact.module').then(m => m.ContactModule) }
];

@NgModule({
  imports: [RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Yukarıdaki örnekte, RouterModule.forRoot() metodu kullanılarak rotalar tanımlanmış ve PreloadAllModules ön yükleme stratejisi ile birlikte kullanılmıştır. Bu strateji, tüm modüllerin ön yüklenmesini sağlar, böylece kullanıcı rotalara hızlı bir şekilde erişebilir.

Bu stratejinin yerine PreloadingStrategy arayüzünü uygulayarak özelleştirilmiş bir ön yükleme stratejisi de tanımlayabilirsiniz. Bu, uygulamanızın ihtiyaçlarına daha iyi uyacak şekilde ön yükleme davranışını yapılandırmanıza olanak tanır.

Ön yükleme stratejileri, Angular Router’da rotaların bileşenlerini önceden yüklemek için güçlü bir araçtır. Bu stratejiler, kullanıcı deneyimini iyileştirmek ve uygulamanın performansını artırmak için kullanılabilir.

Using Angular Router with Angular templates

Angular Router, Angular uygulamalarında sayfalar arası gezinme ve yönlendirme işlevselliğini sağlamak için kullanılır. Angular Router, özellikle tek sayfa uygulamalarında (SPA) çok yaygın olarak kullanılır. Bu, kullanıcıların uygulama içinde gezinirken URL’lerin değişmesini ve tarayıcı geçmişini etkilemeden sayfalar arasında geçiş yapmalarını sağlar.

Angular Router’ı kullanarak, farklı bileşenlerin farklı URL’lerle eşleştirilmesini sağlayabiliriz. Bu, Angular uygulamasında farklı sayfaları temsil eden bileşenlerin tanımlanmasını ve bu bileşenlerin belirli URL’lerle ilişkilendirilmesini sağlar.

RouterLink Kullanımı: HTML şablonlarında RouterLink direktifini kullanarak belirli rotalara yönlendirme yapın.

<a routerLink="/home">Home</a>
<a routerLink="/about">About</a>
<a routerLink="/contact">Contact</a>

RouterOutlet Kullanımı: Ana bileşen şablonunda RouterOutlet direktifini kullanarak farklı rotalara karşılık gelen bileşenlerin yükleneceği alanı belirtin.

<router-outlet></router-outlet>

Parametrelerle Yönlendirme: RouterLink ile parametreler kullanarak dinamik olarak bileşenler arasında gezinme yapın.

<a [routerLink]="['/user', userId]">User Details</a>

Programatik Yönlendirme: TypeScript kodunda Router servisini enjekte ederek programatik yönlendirme yapın.

import { Router } from '@angular/router';

@Component({
  // ...
})
export class MyComponent {
  constructor(private router: Router) {}

  goToAboutPage() {
    this.router.navigate(['/about']);
  }
}

Angular Router, Angular uygulamalarında yönlendirme işlemlerini kolayca yönetmek için kullanılır. RouterLink ve RouterOutlet gibi direktiflerle HTML şablonları içinde yönlendirme yapabilir ve Router servisi aracılığıyla programatik olarak yönlendirme işlemleri gerçekleştirebiliriz. Bu, kullanıcıların uygulama içinde kolayca gezinmelerini sağlar ve SPA’lar için temel bir özelliktir.

Angular signals and the Signal function

Angular’da “signals” terimi, genellikle “observable” veya “stream” terimleriyle eşanlamlı olarak kullanılır. Reactive Programming’in temelini oluşturan bu kavramlar, bir değer veya değerlerin zaman içindeki değişimlerini temsil eden bir veri akışıdır. Angular, Reactive Extensions (RxJS) kütüphanesini kullanarak bu tür sinyalleri işler.

Signal (Observable) Nedir?

Bir sinyal (observable), potansiyel olarak birden çok değeri zaman içinde yayınlayabilen bir veri akışıdır. Sinyal, başlama, durma ve hata bildirimi gibi özel olaylarla ilişkilendirilebilir. Bu, asenkron veri akışlarını temsil etmek için güçlü bir model sağlar.

Angular’da sinyalleri kullanmak için RxJS kütüphanesini Observable sınıfını kullanırız. Bu, sinyalleri oluşturmak, dönüştürmek, birleştirmek ve abone olmak gibi çeşitli işlemleri gerçekleştirmemizi sağlar.

Signal Oluşturma

RxJS, farklı yöntemlerle sinyaller oluşturmamızı sağlar. Bunlardan biri de of() fonksiyonudur. of() fonksiyonu, belirtilen değerleri bir sinyal olarak döndürür.

Örnek:

import { of } from 'rxjs';

const signal = of(1, 2, 3, 4, 5);

Yukarıdaki örnekte, of() fonksiyonu kullanılarak bir sinyal oluşturulmuş ve signal değişkenine atılmıştır. Bu sinyal, 1, 2, 3, 4 ve 5 değerlerini zaman içinde yayınlayacaktır.

Signal Aboneliği (Subscription)

Sinyallere abone olarak, sinyalin yayınladığı değerleri alabiliriz. Bu, sinyalin subscribe() yöntemiyle gerçekleştirilir.

Örnek:

signal.subscribe({
  next: value => console.log(value),
  error: err => console.error('Error occurred:', err),
  complete: () => console.log('Signal completed')
});

Yukarıdaki örnekte, subscribe() yöntemi kullanılarak sinyale abone olunmuştur. next geri çağrısı, sinyal bir değer yayınladığında çağrılır ve bu değer konsola yazdırılır. error geri çağrısı, bir hata oluştuğunda çağrılır ve complete geri çağrısı, sinyal tamamlandığında çağrılır.

Angular’da, sinyalleri kullanarak asenkron operasyonları işlemek ve bileşenler arası iletişimi yönetmek yaygın bir uygulamadır. Özellikle HTTP istekleri, kullanıcı etkileşimleri ve zamanla değişen veriler gibi senaryolarda sinyaller çok faydalıdır.

Angular signals and the Computed function

Angular’da “computed” fonksiyonu, genellikle Reactive Extensions (RxJS) kütüphanesi ile kullanılır. Computed fonksiyonu, sinyallerin (observables) üzerinde dönüşümler gerçekleştirmek için kullanılır. Bu, sinyalleri birleştirmek, dönüştürmek, filtrelemek veya başka işlemler yapmak için kullanılabilir. Computed fonksiyonu, reaktif programlama paradigması içinde sıkça kullanılan bir araçtır ve Angular uygulamalarında veri akışlarını yönetmek için yaygın olarak kullanılır.

Computed Fonksiyonunun Kullanımı

Computed fonksiyonu, RxJS’in pipe ve map operatörleriyle birlikte kullanılarak sinyaller üzerinde dönüşümler yapar. Bu, bir sinyalin değerlerini alır, belirli bir işlemi uygular ve yeni bir sinyal döndürür.

İşte bir örnek:

import { of } from 'rxjs';
import { map } from 'rxjs/operators';

const signal = of(1, 2, 3, 4, 5);

const computedSignal = signal.pipe(
  map(value => value * 2)
);

computedSignal.subscribe(result => console.log(result));

Yukarıdaki örnekte, of() fonksiyonuyla bir sinyal oluşturulmuş ve daha sonra pipe() yöntemi kullanılarak bu sinyalin üzerinde bir dönüşüm gerçekleştirilmiştir. map() operatörü kullanılarak sinyalin her bir değeri iki ile çarpılmıştır. Son olarak, bu dönüştürülmüş sinyale abone olunmuş ve sonuçlar konsola yazdırılmıştır.

Computed fonksiyonu, sinyallerin üzerinde daha karmaşık dönüşümler gerçekleştirmek için de kullanılabilir. Örneğin, sinyalleri birleştirebilir, filtreleyebilir, gruplayabilir veya herhangi bir özel işlemi uygulayabilirsiniz.

Angular uygulamalarında, computed fonksiyonları genellikle bileşenler arasında veri akışını yönetmek ve bileşenlerin görünümünü güncellemek için kullanılır. Özellikle form kontrolleri, tablolar veya listeler gibi dinamik veri görüntüleme alanlarında computed fonksiyonları oldukça faydalıdır. Bu sayede veri değiştiğinde otomatik olarak bileşenlerin güncellenmesi sağlanır, böylece kullanıcılar her zaman en güncel verilere erişebilir.

Angular signals and the Effect function

Angular’da “Effect” fonksiyonu, genellikle Angular tarafından sağlanan “Effect” kütüphanesi aracılığıyla kullanılır. Bu kütüphane, Reactive Extensions (RxJS) kütüphanesinin bir parçasıdır ve Redux gibi durum yönetimi kütüphaneleriyle entegrasyonu sağlar. “Effect” fonksiyonu, Redux’taki “middleware” kavramına benzer bir şekilde, asenkron eylemleri yönetmek ve yan etkileri ele almak için kullanılır.

Effect Fonksiyonunun Kullanımı

Angular’da “Effect” fonksiyonu, @Effect() dekoratörüyle işaretlenen bir sınıf metodunu ifade eder. Bu metod, bir Redux eylemi gönderildiğinde çalışır ve bu eylemi işleyerek yan etkileri gerçekleştirir. Genellikle, HTTP istekleri gönderme, tarayıcı depolama erişimi, yerel veritabanı etkileşimi gibi yan etkilere sahip işlemler burada gerçekleştirilir.

Örnek bir “Effect” fonksiyonu:

import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { mergeMap, map, catchError } from 'rxjs/operators';
import { of } from 'rxjs';
import { UserService } from './user.service';

@Injectable()
export class UserEffects {

  loadUsers$ = createEffect(() => this.actions$.pipe(
    ofType('[User Page] Load Users'),
    mergeMap(() => this.userService.getUsers()
      .pipe(
        map(users => ({ type: '[User API] Users Loaded Success', payload: users })),
        catchError(() => of({ type: '[User API] Users Loaded Error' }))
      ))
    )
  );

  constructor(
    private actions$: Actions,
    private userService: UserService
  ) {}
}

Yukarıdaki örnekte, “Effect” fonksiyonu createEffect() yardımcı fonksiyonu ile tanımlanmıştır. ofType() operatörü, belirli bir eylemin türüne sahip olan eylemleri filtrelemek için kullanılır. mergeMap() operatörü, asenkron bir işlem gerçekleştirmek için kullanılır ve bu durumda kullanıcıları yüklemek için userService.getUsers() metodu çağrılır. Ardından, başarılı bir şekilde kullanıcılar yüklendiğinde bir “success” eylemi veya bir hata oluştuğunda bir “error” eylemi yayınlanır.

Effect fonksiyonları genellikle, ngrx/store veya ngrx/effects gibi durum yönetimi kütüphaneleriyle birlikte kullanılır. Bu kütüphaneler, Angular uygulamalarında durum yönetimini yönetmek için kullanılır ve genellikle Redux tarzı mimarileri takip ederler.

Effect fonksiyonları, Angular uygulamalarında asenkron işlemleri yönetmek, yan etkileri ele almak ve uygulamanın durumunu güncellemek için güçlü bir araçtır. Bu, özellikle büyük ve karmaşık uygulamalarda kullanışlıdır ve uygulamanın verimli ve tutarlı bir şekilde çalışmasını sağlar.

Angular’s async pipe

Angular’da “async pipe”, Reactive Programming’in temel prensiplerinden birini uygulayan ve asenkron veri akışlarını kolayca işlememizi sağlayan güçlü bir araçtır. Bu, sinyalleri (observables) ve promise’leri doğrudan HTML şablonlarında kullanmamıza olanak tanır. Böylece bileşen sınıflarında ekstra kod yazmadan veri akışlarını kolayca yönetebiliriz.

Async Pipe’in Kullanımı

Async pipe’i kullanarak, bir sinyali veya bir promise’i doğrudan HTML şablonunda abone olabiliriz. Angular, bu abonelikleri yönetmek ve otomatik olarak bileşenin yaşam döngüsüne uygun şekilde abonelikleri sonlandırmak için async pipe’i akıllıca kullanır.

Örnek bir kullanım:

<div>
  <p>{{ user$ | async }}</p>
</div>

Yukarıdaki örnekte, user$ adında bir sinyal (observable) veya bir promise HTML şablonunda async pipe’i ile abone edilir. Bu, user$ sinyali veya promise’i tamamlandığında veya yeni bir değer yayımlandığında otomatik olarak güncellenen HTML içeriğini temsil eder.

Async Pipe ile Sinyalleri Kullanma

Örneğin, bir bileşen sınıfında bir sinyal oluşturabiliriz ve bu sinyali async pipe ile HTML şablonunda kullanabiliriz:

import { Component } from '@angular/core';
import { Observable, of } from 'rxjs';
import { delay } from 'rxjs/operators';

@Component({
  selector: 'app-example',
  template: `
    <div>
      <p>{{ data$ | async }}</p>
    </div>
  `,
})
export class ExampleComponent {
  data$: Observable<string>;

  constructor() {
    // Sinyal oluştur
    this.data$ = of('Hello, World!').pipe(delay(2000));
  }
}

Yukarıdaki örnekte, data$ adında bir sinyal (observable) oluşturulmuş ve bu sinyal async pipe ile HTML şablonunda kullanılmıştır. Sinyal, ‘Hello, World!’ değeriyle başlar ve 2 saniye gecikme eklenmiştir. Bu sayede HTML şablonunda ‘Hello, World!’ metni 2 saniye sonra görüntülenecektir.

Async pipe, Angular uygulamalarında asenkron veri işleme süreçlerini kolaylaştırır ve sinyalleri veya promise’leri doğrudan HTML şablonlarında kullanmamızı sağlar. Bu, bileşen sınıflarında gereksiz abonelik yönetimi kodu yazmamızı önler ve kod temizliğini artırır.

RxJS and Reactive programming in Angular

RxJS (Reactive Extensions for JavaScript), Reactive Programming için bir JavaScript kütüphanesidir ve Angular’da çok yaygın olarak kullanılır. Reactive Programming, veri akışlarını ve olayları işlemek için bir paradigmadır. RxJS, bu tür veri akışlarını kolayca yönetmek için bir dizi operatör ve araç sağlar ve Angular’da sık sık kullanılır.

RxJS Temelleri

RxJS, Observable adı verilen ve zaman içinde birden çok değeri temsil eden bir tür sağlar. Bu değerler, akış içinde yayınlanır ve akışın başlangıcından sonuna kadar değişebilir. Bu, sinyallerin veya veri akışlarının temsil edilmesini sağlar.

RxJS’de yaygın olarak kullanılan bazı kavramlar:

Observable: Zaman içinde birden çok değeri temsil eden bir akıştır.

Operatorler: Observable’ları dönüştürmek, birleştirmek, filtrelemek veya manipüle etmek için kullanılan işlevlerdir.

Subscription (Abonelik): Bir Observable’a abone olmayı ifade eder. Abonelik, Observable bir değer yayınladığında veya hata ürettiğinde veya tamamlandığında gerçekleştirilir.

Subject: Hem Observable hem de Observer olabilen bir türdür. Diğer Observable’lara değerler yayınlayabilir ve diğer Observable’lardan değerler alabilir.

RxJS Operatörleri

RxJS’de birçok operatör bulunur ve bu operatörler Observable’ları manipüle etmek için kullanılır. Bazı yaygın RxJS operatörleri şunlardır:

  1. map: Observable’ın her bir değerini dönüştürmek için kullanılır.
  2. filter: Observable’dan belirli değerleri filtrelemek için kullanılır.
  3. mergeMap/switchMap: Bir Observable’dan başka bir Observable’a geçiş yapmak için kullanılır.
  4. combineLatest: Birden çok Observable’dan gelen değerleri birleştirmek için kullanılır.
  5. takeUntil: Belirli bir koşul gerçekleşene kadar Observable’ı takip etmek için kullanılır.
RxJS ve Angular

Angular, RxJS’i kendi temel kütüphanesi olarak kullanır ve özellikle HTTP istekleri, form işlemleri, kullanıcı etkileşimleri gibi asenkron veri akışlarını yönetmek için RxJS çok yaygın olarak kullanılır. Örneğin, HTTP istekleriyle veri almak için Angular HttpClient modülü Observable’ları kullanır ve bu verileri async pipe ile HTML şablonlarında kolayca işler.

Örnek bir HTTP isteği:

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-example',
  template: `
    <ul>
      <li *ngFor="let user of users$ | async">{{ user.name }}</li>
    </ul>
  `,
})
export class ExampleComponent implements OnInit {
  users$: Observable<any>;

  constructor(private http: HttpClient) {}

  ngOnInit() {
    this.users$ = this.http.get<any[]>('https://jsonplaceholder.typicode.com/users');
  }
}

Yukarıdaki örnekte, Angular HttpClient modülü kullanılarak bir HTTP GET isteği gönderilmiş ve gelen veriler users$ Observable’ına atanmıştır. Bu Observable daha sonra async pipe ile HTML şablonunda kullanılarak kullanıcılar listelenmiştir.

RxJS ve Reactive Programming, Angular uygulamalarında veri akışlarını yönetmek için güçlü bir araçtır. RxJS operatörleri ve Observable’lar, karmaşık asenkron işlemleri yönetmeyi ve bileşenler arası iletişimi kolaylaştırmayı sağlar. Bu, Angular uygulamalarının performansını artırabilir ve kodun daha temiz ve okunabilir olmasını sağlar.

Overview of unit testing

Unit testing, bir yazılımın en küçük bileşenlerini (fonksiyonlar, sınıflar, metotlar) ayrı ayrı test etme sürecidir. Angular uygulamalarında, birim testler, bileşenlerin, hizmetlerin, yönlendiricilerin ve diğer Angular yapılarının doğru şekilde çalıştığından emin olmak için yaygın olarak kullanılır. Bu testler, Angular CLI ile oluşturulan projelerde varsayılan olarak sunulan Karma ve Jasmine gibi araçlarla yazılır ve yürütülür.

Unit Testlerin Özellikleri

Bağımsızlık: Unit testler, birbirinden bağımsız olmalıdır. Bir testin sonucu, başka bir testin sonucunu etkilememelidir.

Belirginlik: Her testin neyi test ettiği açık olmalıdır. Test adı, testin neyi kontrol ettiğini açıkça belirtmelidir.

Tekil Sorumluluk: Her testin yalnızca bir işlevi olmalıdır. Birden fazla durumu test eden karmaşık testler yerine, tek bir durumu test eden daha basit testler tercih edilmelidir.

Yinelenme: Testlerin sürekli olarak tekrarlanabilir olması ve her koşulda aynı sonucu üretmesi gerekir.

Hız: Unit testlerin hızlı olması önemlidir. Hızlı testler, geliştirme sürecinin hızını artırır ve geri bildirim döngüsünü hızlandırır.

Angular’da Unit Testlerin Yazılması

Angular uygulamalarında, bileşenlerin, hizmetlerin ve diğer yapıların birim testlerini yazmak için Jasmine test çerçevesi kullanılır. Jasmine, davranışsal testlerin yazılmasını kolaylaştıran bir yapıdır ve yaygın olarak kullanılan bir JavaScript test çerçevesidir. Bu testler, Angular CLI ile oluşturulan projelerde varsayılan olarak sunulan Karma test çalıştırıcısı kullanılarak yürütülür.

Bir örnek unit test dosyası:

import { TestBed } from '@angular/core/testing';
import { MyService } from './my.service';

describe('MyService', () => {
  let service: MyService;

  beforeEach(() => {
    TestBed.configureTestingModule({});
    service = TestBed.inject(MyService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });

  it('should return "Hello, World!"', () => {
    const result = service.sayHello();
    expect(result).toEqual('Hello, World!');
  });
});

Yukarıdaki örnekte, MyService adlı bir hizmetin unit testleri yazılmıştır. describe() bloğu, test suitini tanımlar ve beforeEach() fonksiyonu, her test öncesinde çalıştırılacak hazırlık işlemlerini içerir. it() fonksiyonları ise her bir testi tanımlar. Örneğin, should be created testi, hizmetin doğru şekilde oluşturulduğunu kontrol ederken, should return "Hello, World!" testi, sayHello() metodunun beklenen çıktıyı üretip üretmediğini kontrol eder.

Angular’da birim testler yazmak, kodunuzun kalitesini artırır, hataları erken tespit eder ve güvenliği sağlar. Bu nedenle, Angular uygulamaları geliştirirken, her bir bileşenin ve hizmetin uygun birim testlerinin oluşturulması önemlidir.

Unit testing without dependency injection

Angular’da birim testler genellikle Angular Dependency Injection mekanizmasını kullanarak bileşenlerin test edilmesiyle gerçekleştirilir. Ancak bazı durumlarda, Angular’da dependency injection kullanmadan bileşenlerin birim testlerini yazmak gerekebilir. Bu durumda, bileşenlerin bağımlılıklarını doğrudan oluşturmak ve yönetmek zorunda kalırız.

Dependency Injection Kullanmadan Bileşen Testi Nasıl Yazılır?

Angular bileşenlerini DI kullanmadan test etmek için, doğrudan bileşenin constructor’ında bağımlılıkları oluşturarak veya sahte (mock) bağımlılıklar oluşturarak yapabiliriz.

Örnek bir bileşen sınıfı:

export class Calculator {
  add(a: number, b: number): number {
    return a + b;
  }
}

Bu bileşeni DI kullanmadan test etmek için, test dosyasında bir Calculator örneği oluşturabiliriz ve ardından bu örneği kullanarak işlemleri gerçekleştirebiliriz.

Örnek bir test dosyası:

import { Calculator } from './calculator';

describe('Calculator', () => {
  let calculator: Calculator;

  beforeEach(() => {
    calculator = new Calculator();
  });

  it('should add two numbers correctly', () => {
    const result = calculator.add(3, 5);
    expect(result).toEqual(8);
  });
});

Yukarıdaki örnekte, Calculator sınıfının add() metodunu doğrudan çağırarak test edilir. Herhangi bir DI olmadan, Calculator sınıfının yeni bir örneği test sürecinin her beforeEach() işlevi çağrıldığında oluşturulur.

Mock Bağımlılıkların Kullanımı

Bazen bileşenlerimiz, dış kaynaklara (HTTP istekleri, servisler vb.) bağımlı olabilir ve bu durumda bu bağımlılıkları test edemeyiz. Bu durumlarda, mock bağımlılıklar oluşturarak bu bağımlılıkların yerine kullanabiliriz.

Örnek bir bileşen sınıfı:

import { Injectable } from '@angular/core';

@Injectable()
export class DataService {
  getData(): string {
    return 'Data from service';
  }
}

Bu servisi kullanarak bir bileşen sınıfı:

import { Injectable } from '@angular/core';

@Injectable()
export class DataProcessor {
  constructor(private dataService: DataService) {}

  processData(): string {
    const data = this.dataService.getData();
    return data.toUpperCase();
  }
}

Dependency Injection kullanmadan bileşen sınıfının test edilmesi için, DataService’yi simüle eden bir mock oluşturabiliriz.

class MockDataService {
  getData(): string {
    return 'Mocked data';
  }
}

describe('DataProcessor', () => {
  let dataProcessor: DataProcessor;

  beforeEach(() => {
    dataProcessor = new DataProcessor(new MockDataService());
  });

  it('should process data correctly', () => {
    const result = dataProcessor.processData();
    expect(result).toEqual('MOCKED DATA');
  });
});

Yukarıdaki örnekte, DataProcessor sınıfını test etmek için MockDataService kullanılmıştır. Böylece, DataProcessor sınıfının processData() metodu, gerçek bir DataService kullanılarak değil, mock veri kullanılarak test edilmiştir.

Angular’da dependency injection kullanmadan bileşenlerin test edilmesi, bazı durumlarda gerekebilir ve bu tür senaryolarda mock bağımlılıkların kullanılması önemlidir. Bu şekilde, bileşenlerimizin doğru şekilde çalışıp çalışmadığını test etmek mümkün olur.

Unit testing with dependency injection

Angular’da dependency injection (DI), bileşenlerin, hizmetlerin ve diğer yapıların bağımlılıklarının yönetilmesini sağlayan önemli bir özelliktir. Unit testlerde dependency injection kullanarak Angular bileşenlerini test etmek oldukça yaygındır. Bu, testlerin daha temiz ve modüler olmasını sağlar ve bileşenlerin gerçek dünya senaryolarına daha yakın bir şekilde test edilmesine olanak tanır.

Dependency Injection Kullanarak Bileşen Testi Nasıl Yazılır?

Angular’da bileşenleri test etmek için Jasmine ve Angular Test Bed kullanılır. Angular Test Bed, bileşenlerin bağımlılıklarını enjekte etmemize ve bileşenleri test etmemize olanak tanır. Böylece, bileşenin gerçek dünya senaryolarına daha yakın bir şekilde test edilmesini sağlar.

Örnek bir bileşen sınıfı:

import { Injectable } from '@angular/core';

@Injectable()
export class DataService {
  getData(): string {
    return 'Data from service';
  }
}

Bu servisi kullanarak bir bileşen sınıfı:

import { Injectable } from '@angular/core';
import { DataService } from './data.service';

@Injectable()
export class DataProcessor {
  constructor(private dataService: DataService) {}

  processData(): string {
    const data = this.dataService.getData();
    return data.toUpperCase();
  }
}

Bileşen testi için birim test dosyası:

import { TestBed, ComponentFixture } from '@angular/core/testing';
import { DataProcessor } from './data-processor.component';
import { DataService } from './data.service';

describe('DataProcessor', () => {
  let component: DataProcessor;
  let fixture: ComponentFixture<DataProcessor>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [DataProcessor],
      providers: [DataService]
    }).compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(DataProcessor);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create the component', () => {
    expect(component).toBeTruthy();
  });

  it('should process data correctly', () => {
    const mockData = 'Mocked data';
    const dataService = TestBed.inject(DataService);
    spyOn(dataService, 'getData').and.returnValue(mockData);

    const result = component.processData();
    expect(result).toEqual(mockData.toUpperCase());
  });
});

Yukarıdaki örnekte, DataProcessor bileşeninin birim testleri yer almaktadır. TestBed.configureTestingModule() ile TestBed tarafından bir test modülü oluşturulur ve providers kısmında bağımlılıklar belirtilir. TestBed.createComponent() ile bileşenin bir örneği oluşturulur ve TestBed.inject() ile bağımlılıklar enjekte edilir. Testler, bu bileşen örneği üzerinde gerçekleştirilir.

Özellikle, ikinci testte DataService‘ye mock verisi sağlanır ve getData() metodunun çıktısı toUpperCase() ile kontrol edilir. Bu şekilde, bileşenin doğru şekilde çalışıp çalışmadığı test edilmiş olur.

Dependency Injection kullanarak Angular bileşenlerini test etmek, testlerin daha temiz ve modüler olmasını sağlar ve bileşenlerin gerçek dünya senaryolarına daha yakın bir şekilde test edilmesine olanak tanır. Bu sayede, uygulamanın kalitesini artırır ve güvenilirliğini sağlar.

Static code linting in Angular

Angular projelerinde statik kod denetimi için genellikle TSLint veya son zamanlarda daha yaygın hale gelen ESLint kullanılır. Bu araçlar, kod tabanınızı analiz eder, yaygın hataları ve kötü uygulama kalıplarını belirler ve kodunuzu standartlara uygun hale getirmenize yardımcı olur.

TSLint ve ESLint
TSLint

TSLint, TypeScript projelerinde kullanılan statik kod analiz aracıdır. Angular CLI’nin eski sürümleriyle birlikte gelir ve genellikle Angular projelerinde yaygın olarak kullanılmıştır. Ancak, Angular 10 ve sonraki sürümlerde TSLint yerine ESLint kullanımı önerilir.

ESLint

ESLint, JavaScript projelerinde kullanılan bir statik kod analiz aracıdır. Angular CLI’nin yeni sürümleriyle birlikte ESLint, Angular projelerinde standart olarak kullanılmaya başlanmıştır. TypeScript desteği sağlar ve TypeScript projelerinde TSLint’in yerini almıştır.

Angular’da Statik Kod Denetimi Nasıl Yapılır?

Proje Oluşturma: Angular CLI ile yeni bir proje oluşturduğunuzda, Angular 10 ve sonraki sürümlerde varsayılan olarak ESLint entegre edilir.

Lint Komutu: Angular CLI ile birlikte gelen lint komutu (ng lint), proje dosyalarınızı statik olarak denetler ve hataları/uyarıları raporlar.

Lint Konfigürasyonu: Projenizdeki lint ayarlarını yapılandırmak için eslint.json dosyasını veya angular.json dosyasındaki lint özelliklerini kullanabilirsiniz.

Editor Entegrasyonu: Çoğu modern kod editörü, statik kod denetimi araçlarıyla entegre olmuştur. Bu sayede kod yazarken hataları anında görebilirsiniz.

Örnek Kod

Bir Angular projesinde statik kod denetimi yapmak için genellikle aşağıdaki adımları izlersiniz:

Angular CLI ile yeni bir proje oluşturun:

ng new my-angular-project

Proje klasörüne gidin ve lint komutunu çalıştırın:

cd my-angular-project
ng lint
  1. Statik kod denetim sonuçlarını gözlemleyin ve gerekirse düzeltmeler yapın.
  2. Projenizdeki lint ayarlarını gerektiğinde yapılandırın.
  3. Kod editörünüzde ESLint veya TSLint eklentisi kullanarak hataları ve uyarıları gözden geçirin ve düzeltin.

Bu adımlar sayesinde Angular projenizdeki kod kalitesini koruyabilir ve geliştirebilirsiniz. Statik kod denetimi, projenizin temiz ve düzenli kalmasına yardımcı olur ve ekip üyeleri arasında tutarlı bir kodlama standartı sağlar.


Russet renkli boğazlı kazak ve beyaz çantalı bir kadının yandan profili. Gözleri kapalı yukarı bakıyor.

Kısa vadede acımasızca dürüst olun, uzun vade için ise iyimser ve kendinizden emin olun.

Reed Hastings

Bir sonraki yazıda görüşmek dileğiyle!”

Leave a Reply

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


8 + 2 = ?