Angular Control Flow Sözdizimi 2026: @if, @for, @switch ve Mülakat Soruları

Angular'da blok tabanlı control flow sözdizimi için kapsamlı rehber. @if, @for, @switch kullanımını pratik kod örnekleriyle öğrenin ve teknik mülakatlarına hazırlanın.

Angular Control Flow Syntax diagram

Angular'ın control flow sözdizimi (@if, @for, @switch), yıllardır Angular şablonlarına hakim olan yapısal direktifler *ngIf, *ngFor ve *ngSwitch'in yerini almaktadır. Angular 17'de tanıtılan, Angular 18'den itibaren stabil olan ve Angular 22'de varsayılan hale gelen bu blok tabanlı sözdizimi, şablonları standart programlama yapılarına yaklaştırırken daha iyi performans optimizasyonları sağlamaktadır.

Migrasyon mevcut

ng generate @angular/core:control-flow komutunu çalıştırarak mevcut şablonları yapısal direktiflerden yeni control flow sözdizimine otomatik olarak geçirebilirsiniz. Her iki sözdizimi de migrasyon sürecinde birlikte var olabilir, ancak ngIf, ngFor ve ngSwitch Angular 19'dan itibaren yumuşak bir şekilde kullanımdan kaldırılmıştır.

Angular Neden Yapısal Direktifleri Blok Sözdizimi ile Değiştirdi

Yapısal direktifler CommonModule import edilmesini gerektiriyor, JavaScript'ten farklı mikro sözdizimi kullanıyor ve karmaşık koşullar için geliştiricileri içeriği ng-template içine sarmaya zorluyordu. Yeni control flow sözdizimi bu sorunları çözmektedir:

  • Import gerektirmez: @if, @for ve @switch framework'e yerleşiktir
  • JavaScript benzeri sözdizimi: koşullar ve döngüler standart kod gibi okunur
  • Native @else desteği: else dalları için artık ng-template referanslarına gerek yoktur
  • Daha iyi tree-shaking: kullanılmayan control flow blokları paket boyutunu etkilemez

Angular dokümantasyonu, tüm yeni projelerde blok sözdiziminin tamamen benimsenmesini ve mevcut kod tabanlarının kademeli olarak geçirilmesini önermektedir.

@if: ng-template Olmadan Koşullu Render

@if bloğu, doğru bir ifadeye bağlı olarak içeriği koşullu olarak render eder. *ngIf'ten farklı olarak, @else if ve @else dallarını doğrudan destekler:

user-status.component.tstypescript
import { Component, input } from '@angular/core';

@Component({
  selector: 'app-user-status',
  template: `
    @if (user().role === 'admin') {
      <app-admin-panel />
    } @else if (user().role === 'editor') {
      <app-editor-panel />
    } @else {
      <app-viewer-panel />
    }
  `
})
export class UserStatusComponent {
  user = input.required<{ role: string }>();
}

@if bloğu ayrıca as anahtar kelimesiyle değişken takma adı destekler, bu da iç içe geçmiş ifadelerden değerleri çıkarır:

html
<!-- Tekrarlanan özellik erişimini önler -->
@if (user().profile?.settings?.theme; as theme) {
  <p>Mevcut tema: {{ theme }}</p>
}

Bu kalıp, asenkron verilerle veya derin iç içe geçmiş nesnelerle çalışırken özellikle kullanışlıdır, çünkü takma ad verilen değişken yalnızca koşul doğru olduğunda tanımlanır.

@for: Zorunlu Track İfadesiyle İterasyon

@for bloğu, herhangi bir JavaScript iterable üzerinde iterasyon yapar ve diziler için optimizasyonlar sunar. *ngFor'dan farklı olarak, bir track ifadesi gerektirir:

product-list.component.tstypescript
import { Component, input } from '@angular/core';

interface Product {
  id: string;
  name: string;
  price: number;
}

@Component({
  selector: 'app-product-list',
  template: `
    @for (product of products(); track product.id) {
      <div class="product-card">
        <h3>{{ product.name }}</h3>
        <p>{{ product.price | currency }}</p>
      </div>
    } @empty {
      <p>Ürün bulunamadı</p>
    }
  `
})
export class ProductListComponent {
  products = input.required<Product[]>();
}

track ifadesi zorunludur çünkü Angular'ın diff algoritmasının change detection döngüleri arasında öğeleri tanımlamasını sağlar. Bu sayede framework hangi DOM öğelerinin yeniden kullanılacağını ve hangilerinin yeniden oluşturulacağını bilir.

@for İçinde Bağlam Değişkenlerine Erişim

@for bloğu çeşitli bağlam değişkenleri sunar:

html
@for (item of items(); track item.id; let idx = $index, first = $first, last = $last) {
  <div [class.first-item]="first" [class.last-item]="last">
    {{ idx + 1 }}. {{ item.name }}
  </div>
}

Kullanılabilir bağlam değişkenleri:

  • $index - mevcut indeks (0'dan başlar)
  • $first - ilk öğe mi
  • $last - son öğe mi
  • $even - indeks çift mi
  • $odd - indeks tek mi
  • $count - koleksiyondaki toplam öğe sayısı

@switch: ng-container Olmadan Çoklu Dallanma

@switch bloğu, iç içe geçmiş ng-container öğelerine ihtiyaç duymadan çoklu koşul senaryolarını ele alır:

notification.component.tstypescript
import { Component, input } from '@angular/core';

type NotificationType = 'success' | 'warning' | 'error' | 'info';

@Component({
  selector: 'app-notification',
  template: `
    @switch (type()) {
      @case ('success') {
        <div class="alert alert-success">
          <span class="icon-check"></span>
          <ng-content />
        </div>
      }
      @case ('warning') {
        <div class="alert alert-warning">
          <span class="icon-warning"></span>
          <ng-content />
        </div>
      }
      @case ('error') {
        <div class="alert alert-error">
          <span class="icon-error"></span>
          <ng-content />
        </div>
      }
      @default {
        <div class="alert alert-info">
          <span class="icon-info"></span>
          <ng-content />
        </div>
      }
    }
  `
})
export class NotificationComponent {
  type = input<NotificationType>('info');
}

@switch bloğu katı karşılaştırma (===) kullanır, bu da tip zorlamasıyla ilgili beklenmedik davranışları ortadan kaldırır.

Control Flow Bloklarını İç İçe Kullanma

Control flow blokları karmaşık render mantığı oluşturmak için serbestçe iç içe kullanılabilir:

html
@if (isLoading()) {
  <app-skeleton-loader />
} @else {
  @for (category of categories(); track category.id) {
    <section class="category">
      <h2>{{ category.name }}</h2>
      @for (product of category.products; track product.id) {
        @switch (product.availability) {
          @case ('in_stock') {
            <app-product-card [product]="product" />
          }
          @case ('pre_order') {
            <app-preorder-card [product]="product" />
          }
          @default {
            <app-out-of-stock-card [product]="product" />
          }
        }
      } @empty {
        <p>Bu kategoride ürün yok</p>
      }
    </section>
  } @empty {
    <p>Görüntülenecek kategori yok</p>
  }
}

Yeni Sözdizimi ile Performans Optimizasyonları

Yeni control flow sözdizimi önemli performans iyileştirmeleri sağlar:

Daha Hızlı Change Detection

track ifadesine sahip @for blokları, Angular'ın koleksiyonları daha verimli karşılaştırmasını sağlar. Framework, izlenen değerin kimliğine dayanarak değişmeyen öğelerin kontrolünü atlayabilir.

Daha İyi Minifikasyon

Blok sözdizimi CommonModule'dan import gerektirmediğinden, kullanılmayan bloklar production build sırasında tamamen kaldırılabilir.

@defer Optimizasyonu

Control flow sözdizimi, lazy loading için @defer ile birlikte çalışır:

html
@defer (on viewport) {
  @for (item of heavyItems(); track item.id) {
    <app-heavy-component [data]="item" />
  }
} @placeholder {
  <div class="placeholder">Yükleniyor...</div>
}

Yapısal Direktiflerden Migrasyon

Migrasyon süreci yerleşik şema sayesinde basittir:

bash
ng generate @angular/core:control-flow

Şematik otomatik olarak dönüştürür:

Eski SözdizimiYeni Sözdizimi
*ngIf="condition"@if (condition) { }
*ngIf="condition; else elseBlock"@if (condition) { } @else { }
*ngFor="let item of items"@for (item of items; track item) { }
*ngFor="let item of items; trackBy: trackFn"@for (item of items; track trackFn($index, item)) { }
[ngSwitch] + *ngSwitchCase@switch + @case

Angular mülakatlarında başarılı olmaya hazır mısın?

İnteraktif simülatörler, flashcards ve teknik testlerle pratik yap.

Angular Control Flow Mülakat Soruları

Aşağıda yeni control flow sözdizimi hakkında teknik mülakatlarda sıkça sorulan sorular bulunmaktadır.

Soru 1: Track ifadesi @for'da neden zorunludur?

Cevap: track ifadesi zorunludur çünkü Angular'ın diff algoritmasına koleksiyondaki her öğe için benzersiz bir tanımlayıcı sağlar. Bu, framework'ün koleksiyondaki değişiklikler sırasında hangi DOM öğelerinin yeniden kullanılacağını, güncelleneceğini veya kaldırılacağını verimli bir şekilde belirlemesini sağlar. Tracking olmadan Angular, her değişiklikte tüm listeyi yeniden render etmek zorunda kalır ve bu da performansı önemli ölçüde etkiler.

Soru 2: @if derin iç içe geçmiş opsiyonel özellikleri nasıl ele alır?

Cevap: @if bloğu, iç içe geçmiş bir ifadeden değeri çıkarıp blok içinde kullanmayı sağlayan as anahtar kelimesiyle değişken takma adını destekler. Sözdizimi @if (ifade; as takmaAd) şeklindedir. Takma ad verilen değişken yalnızca ifade doğru olduğunda kullanılabilir, bu da şablonda tekrarlanan opsiyonel zincirleme operatörlerine olan ihtiyacı ortadan kaldırır.

Soru 3: @switch, *ngSwitch'ten nasıl farklıdır?

Cevap: @switch framework'e yerleşiktir ve import gerektirmez. Direktif nitelikleri yerine native blok sözdizimi kullanır. Sarmalayan ng-container öğelerine olan ihtiyacı ortadan kaldırır. Tip zorlamasından kaynaklanan beklenmedik eşleşmeleri önleyen katı karşılaştırma (===) kullanır. Her @case ve @default bağımsız bloklardır, bu da kod okunabilirliğini artırır.

Soru 4: @for'da indeks ve diğer meta verilere nasıl erişilir?

Cevap: @for bloğu let sözdizimi aracılığıyla bağlam değişkenleri sunar: @for (item of items; track item.id; let i = $index, f = $first). Kullanılabilir değişkenler $index, $first, $last, $even, $odd ve $count'tur. Bu değişkenler yerel takma adlara atanabilir ve blok içinde kullanılabilir.

Soru 5: @for, Map ve Set nesneleriyle kullanılabilir mi?

Cevap: Evet, @for bloğu Map, Set ve generator'lar dahil JavaScript iterator protokolünü uygulayan herhangi bir nesne üzerinde iterasyon yapar. Map için iterasyon, şablonda destructure edilebilen [anahtar, değer] çiftleri döndürür.

Soru 6: @empty nasıl çalışır ve ne zaman tetiklenir?

Cevap: @empty bloğu, @for içindeki koleksiyon boş olduğunda (sıfır uzunlukta) veya iterable nesne hiç öğe döndürmediğinde görüntülenir. Bu, items.length === 0 kontrolü yapıp alternatif içerik render etmenin yerleşik karşılığıdır. @empty bloğu isteğe bağlıdır.

Soru 7: Yeni control flow sözdiziminin performans avantajları nelerdir?

Cevap: Yeni sözdizimi birçok performans avantajı sunar: import yükü yok (direktifler için sıfır ek kod), daha iyi tree-shaking (kullanılmayan kod yolları elenir), zorunlu tracking sayesinde daha verimli change detection ve sözdizimi runtime'da yorumlanmak yerine statik olarak parse edildiğinden gelecekteki derleyici optimizasyonları için potansiyel.

Control Flow Sözdizimi İçin En İyi Uygulamalar

Yeni control flow sözdizimini uygularken birkaç kurala uymak faydalıdır:

  1. Track'te her zaman benzersiz tanımlayıcılar kullanın - değişebilen koleksiyonlar için track $index yerine track item.id tercih edin
  2. Daha iyi UX için @empty kullanın - daha iyi kullanıcı deneyimi için her zaman boş liste durumunu tanımlayın
  3. İfadelerde karmaşık mantıktan kaçının - karmaşık hesaplamaları component'e taşıyın
  4. İç içe geçmiş özellikler için takma ad kullanın - derin iç içe geçmiş opsiyonel ifadeler için as kullanın
  5. Kademeli olarak geçiş yapın - her iki sözdizimi de birlikte var olabilir, böylece dosya dosya geçiş yapılabilir

Sonuç

Angular'daki control flow sözdizimi, şablon yazma biçiminde temel bir değişimi temsil etmektedir. @if, @for ve @switch blokları, JavaScript'ten ilham alan daha sezgisel bir sözdizimi sunar, CommonModule import etme ihtiyacını ortadan kaldırır ve zorunlu tracking ile derleyici optimizasyonları sayesinde daha iyi performans sağlar. Yeni Angular projeleri başlatan ekipler için yeni sözdizimi varsayılan tercih olmalıdır. Mevcut projeler için, ng generate @angular/core:control-flow şemasıyla otomatik migrasyon, regresyon riski olmadan sorunsuz bir geçiş sağlar.

Günün meydan okuması

Angular kodundaki hatayı bulabilir misin?

Gerçek bir kod parçası, gizli bir hata, günde bir deneme. Denemek için hesap gerekmez.

Anthony Fillion-Maillet

Yazan:

Anthony Fillion-Maillet

SharpSkill kurucusu

10 yılı aşkın süredir fullstack geliştirici. SharpSkill’i yönetiyor ve burada yayımlanan her şeyden sorumlu.

3 Eylül 2026 tarihinde güncellendi

Etiketler

#angular
#angular-17
#angular-control-flow
#frontend
#typescript

Paylaş

İlgili makaleler