Angular2 / Mimariye Genel Bakış

bora

Mimariye Genel Bakış:


Angular , HTML ve Javascript dilleri ile client uygulamaları geliştirmeye yarayan bir frameworktur. Direk olarak Javascript kullanılmadan, Typescript yazarak da ilgili kodu Javascript diline çevirmek mümkün.


Framework içerisinde kullanılması zorunlu olan ve opsiyonel olan bir çok kütüphane bulunmaktadır.

Angular ile uygulama geliştirirken anguların kendi markup syntax ı ile HTML template  geliştirir , bu templateleri yönetebilmek için component ler yazar, iş mantığını kodlamak için service sınıfları yaratır ve tüm bu bileşenleri de module altında birleştirirsiniz.

Her angular uygulaması içerisinde mutlaka bir tane kök module ( root module) olmak zorundadır. Siz geliştirdiğiniz tüm bileşenleri bu module üzerinden önyükleme ( bootstrapping ) yaparak uygulamanızı başlatırsınız. Angular, uygulama içeriğinizi tarayıcıda göstermek ve kullanıcı etkileşimlerini sizin belirlediğiniz talimatlara göre yanıtlamakla görevlidir.


Tabii ki bundan çok daha fazlası var ama şimdilik büyük resme bakarak bu bileşenleri ve görevlerini anlamaya çalışalım .
overview2

Yukarıdaki resim anguların temel 8 yapı taşını göstermektedir.

  • Modules
  • Components
  • Templates
  • Metadata
  • Data binding
  • Directives
  • Services
  • Dependency injection

Şimdi bu bileşenlere biraz daha yakından bakalım .

Modules


app-module

Angular uygulamaları modular olarak tasarlanmıştır ve buna angular jargonunda Angular Modules ya da NgModules denir.

Daha önce de söylediğimiz gibi her angular uygulaması en az bir module sıfını barındırmak zorundadır ( Root Module ) ve bu genelde AppModule olarak adlandırılır.

Küçük uygulamalarda tek bir root module ile devam edilebilirken , çoğu büyük uygulama birden fazla module ile geliştirilmektedir. Root module dışındaki bu modullere feature module denebilir  ,bunlar uygulama içerisindeki ayrı program akışları , süreçleri , widgets gibi moduller olabilir.

Angular modulleri ( root veya feature ) aslında @NgModule decoratoru ile işaretlenmiş sınıflardır.

Decoratorler javascript sınıflarını değiştiren birer fonksiyon olarak düşünülebilir.Angular içerisinde birçok decorator vardır ve bunlar sınıfların ne amaçla tasarlandıklarını belirtirler. Decoratorler ile ilgili buradan daha fazla bilgiye ulaşabilirsiniz. İleride bu kaynakla ilgili de bir çeviri şansımız belki olabilir.

@NgModule içerisinde module tanımını yapmamızı sağlayan birçok özellik ( property ) bulunmaktadır.

  • declarations –  ilgili module e ait olan görünüm sınıflarını( view classes ) belirtmemizi sağlar. Angular içerisinde üç tip view class vardır. ( Components , Directives ve Pipes )
  • exportsdeclarations özelliğinin bir alt kümesi olmak zorundadır. Bu module içerisinde declare edilen sınıflardan , diğer modullerde kullanılacak olanlar varsa burada belirtirilir.
  • imports – bu özellik de diğer moduller tarafından export edilen ve bu modulde kullanılacak olan sınıfları belirtmemizi sağlar.
  • providers – Uygulama genelinde kullanacağımız service sınıflarını burada tanımlarız . Böylece tüm module elemanlarında bu service sınıfında tek bir instance olacağını garanti altına almış oluruz.
  • bootstrap – Uygulamanın ana görünümüdür, root component olarak adlandırılır. Tüm diğer uygulama görünümlerini barındırır. Sadece root module bu özelliği kullanmalıdır.

Örnek bir root module :

simple-root-module

Buradaki AppComponent export aslında gerçekte gerekli olan bir koşul değil, örneklemek amacıyla eklendi. Root module herhangi bir sınıf export etmek zorunda değil , çünkü diğer component ler root module sınıfını import etmek zorunda değiller.

Uygulamanızı root module sınıfını bootstrap ederek başlatın. Geliştirme sırasında AppModule bootstrap işlemini aşağıdaki örnekte bulunan main.ts dosyasındaki gibi yapabilirsiniz.

bootstrap-main-ts

 Angular libraries


Angular Javascript modullerini bir araya getirir. Her angular library ismi @angular ile başlar.

Angular library lerini npm paket yöneticisi ile yükler ve bu library ler içerisinden kullanmak istediğiniz sınıfları da import cümleleri ile ilgili sınıflarınıza eklersiniz.( Aslında java daki importlar gibi düşünülebilir. Import edilen sınıf bizim projemizde bulunan x bir sınıf olabildiği gibi , classpaath imizde bulunan a.jar içerisindeki y sınıfı da olabilir )
Angular ın Component decorator unu @angular/core library si içerisinde aşağıdaki şekilde import edebilirsiniz.

import { Component } from ‘@angular/core’;

Aynı zamanda Angular modullerini aşağıdaki gibi Angular library leri içerisinde Javascript cümlesi ile de import edebilirsiniz.

import { BrowserModule } from ‘@angular/platform-browser’;

Yukarıdaki örnekte application module BrowserModule sınıfını import etmiş ve aşağıdaki gibi de @NgModule decoratorunun imports property sinde de bu sınıfı kullanacağını belirtmiş.

imports: [ BrowserModule ],

Bu şekilde Angular ve Javascript modullerini bir arada kullanabilirsiniz

In this way you’re using both the Angular and JavaScript module systems together.

Hem Angular hem de Javascript sistemlerini bu şekilde karıştırmak ve anlamak zor olabilir çünkü import ve export akışlarında iki sistem de aynı dili kullanmaktadır. Zamanla bu karmaşa deneyimlerinizin artması ile birlikte azalacaktır.

Components


Ekranı kontrol eden bileşenlere(sınıf) Component denmektedir.

Örnek olarak aşağıdaki view lar componentler tarafından kontrol edilmektedir.

  • App Root ile navigation linklerinin yönetimi.
  • Heroes listesi ekranı
  • Hero düzenleme  ekranı

Uygulama view içerisindeki iş mantığını component sınıfı içerisinde tanımlarsınız. Bu sınıf ekran ile API ve property ler aracılığı ile etkileşim içerisindedirler.

Örnek verelim , aşağıda HeroListComponent isminde bir component sınıfımız var ve bu sınıf hero isimli modelimize ait bir listeyi göstermek üzere tasarlanmış bir view a ait olsun. Bu sınıf içerisinde hero listesini saklayan bir array imiz var ( heroes ) , bu array bir service sınıfı sayesinde doldurulmakta , aynı zamanda bu component sınıfı içerisinde selectHero() isminde bir method bulunuyor ve kullanıcı ekrandaki listeden x bir elemana ( hero oluyor bu örnekte ) tıkladığında bu method çalıştırılıyor.

hero-list-component

Kullanıcı uygulama içerisinde gezindikçe , angular tarafından uygulama içerisinde aktif olan görünümlere ait componentler yaratılır/güncellenir/silinir . Bu yaşam döngüsü angular tarafından yönetilmektedir. İleride angular yaşam döngüsünü detaylı bir şekilde ele alacağız. Yukarıdaki örnekte bu yaşan döngüsünün bir adımı olan ngOnInıt metodu gerçeklenmiştir.

Metadata


Metadata angular içerisindeki bir class ın ( sınıf ) nasıl işletileceğini yani hangi tip bir bileşen olduğunu söylememize yarar.

Yukarıdaki HeroListComponent sınıfımıza dönecek olursak , bu sınıfın herhangi bir metadata decoratoru bulunmamaktadır. Aslında bu sınıfın şu an için Angular framework içerisinde kullanıldığına dair bir ifade bulunmamaktadur.

Bu şartlarda HeroListComponent sadece bir class tır ve siz bunu Component metadatası ile işaretlemediğiniz sürece Angular tarafından Component olarak yorumlanmayacaktır.

Typescript ile geliştirme yaparken classlarımıza metadata ekleyebilmek için decorator ler kullanılmaktadır ( Javadaki karşılığı Annotations olabilir )

hero-list-component-metadata

Burada karşımıza @Component decoratoru çıkmaktadır, bu decorator bu sınıfın @Component tipinde bir sınıf olduğunu Angular a söyler.

Bu @Component decoratoru içerisinde Anguların bu componenti ve view bileşenini yaratabilmesi için ihtiyaç duyduğu bilgiler yer almaktadır.

Aşağıda ençok kullanılan @Component konfigurasyon parametreleri açıklamaları bulunmaktadır.

  • selector: Bu bilgi ile uygulama içerisinde ilgili sınıfın görünümünün hangi lokasyonda gösterileceğini belirtiriz. Bu örnek için hero-list selectoru kullanılmış ve bu da HTML içerisinde taglerinin görüldüğü yerde bu component içerisinde tanımlanmış olan template içeriğinin gösterileceğini belirtir.
  • templateUrl: selector taglerinin olduğu bölümde gösterilecek olan içeriği belirtir.
  • providers: ilgili componentin kullanmak istediği service sınıflarının bir listesini tutar. Bu örnek için HeroService sınıfıdır.

@Component metadatası içerisinde Anguların bu component i yaratabilmesi için gerekli olan bilgiler yer almaktadır da diyebiliriz.

Template , metadata ve component bileşenleri birlikte view ları tanımlarlar.

Angular Framework içerisinde sık kullanılan decoratorlere @Injectable, @Input, ve@Output decoratorlerini verebiliriz.

Mimari açıdan baktığımızda, yarattığınız sınıflara verdiğini bu decoratorler sayesinde Angular Framework bu sınıfları nasıl işleteceğini öğrenmiş olur.

Data Binding


Framework kullanmadığınız zaman verilerin ekrana getirilmesi, kontrol edilmesi , kullanıcı hareketleri ile veri güncellemeleri gibi işlemleri koordine etmek sizin sorumluluğunuzdadır. Bu şekilde geliştirmek de hem hata eğilimi yüksek hem de geliştirilen kodun okunulabilirliğini düşük tutmamıza neden olacaktır.

Data Binding

Angular data binding işlemlerini destekler, bu aslında template parçaları ile componentler arasındaki koordinasyonu sağlar.  HTML template içerisine binding özellikleri ekleyerek iki katmanın nasıl haberleşeceklerini de söylemiş olursunuz.

Yukarıdaki diagramda da görüldüğü gibi 4 tip data binding yaklaşımı vardır. Bunlar DOM tarafına , DOM tarafından ve çift yönlü şekilde gerçeklenebilirler.

HeroListComponent 3 tip data binding için güzel bir örnek teşkil eder :

data-binding-hero-list-component

  • {{hero.name}} syntax ı  component içerisindeki hero sınıfının name özelliğini template içerisinde
  • tagleri arasında göstermemizi sağlar.
  • The [hero] ise HeroListComponent içerisindeki selectedHero özelliğini HeroDetailComponent içerisindeki hero özelliğine set eder.
  • The (click) event binding ise component içerisindeki selectHero metodunu çağırır.

Two-way data binding property ve event binding işlemlerini  ngModel directive ile basit bir şekilde gerçekleştirmeyi sağlar. Aşağıda HeroDetailComponent için örnek bulunmaktadır.

Two-way data binding ile property değerleri component ile template arasında etkileşim içerisinde kalır. Kullanıcının ekrandan değiştirdiği değer , component üzerindeki modele yansırken , component içerisinden değiştirilen propery değeri de ekrana aynı şekilde yansımaktadır.

Angular tüm data binding işlemlerini Javascript event cycle ile root application ile tüm alt componentler arasında gerçekleştirir.

Data Binding

Data binding işlemi template ile componentler arasındaki iletişimin önemli bir parçasıdır.

Parent/Child binding

Directives


Angular templateleri dinamik olarak oluşturulur . Angular bunları ekranda çizerken DOM elemanlarını directive ler tarafından verilen bilgilere göre HTML elemanlarına çevirir.

Directiveler, @Directive decoratoru ile işaretlenmiş classlardır Component sınıfları template özellikleri olan birer directive lerdir denebilir. Zaten @Component sınıfı Angular içerisinde geliştirilirken @Directive sınıfından miras alarak ( extended ) template bazlı yeni özellikler eklenerek geliştirilmiştir.

Componentler teknik açıdan birer directive olsa da , component sınıfları angular framework içerisinde kullanımları açısından ( mimari olarak ) directivelerden net bir şekilde ayrılırlar.

İki çeşit directive bulunur . structural ve attribute 

Structural directiveler layout u değiştirmek , eklemek , çıkarmak gibi DOM manuplasyon işlemlerini gerçekleştirir.

Aşağıdaki örnekteki iki tane Angular içinde tanımlı structural directive e bakacak olursak:

structural-directives

  • *ngFor direcitve i angulara , HeroListComponent içerisindeki heroes arrayindeki her bir hero elemanı için
  • elemanı basılacağını söyler.
  • *ngIf directive ise HeroListComponent içerisindeki selectedHero property si dolu olduğu zaman componentinin ekranda çizilmesi gerektiğini belirtir.

Attribute directive ler ise HTML içindeki elemanların görünümlerini ve davranışlarını değiştirir. Template içerisinde sanki birer HTML attribute leriymiş gibi görünürler.

Örneğin ngModel directive ine bakacak olursak, two-way data binding işlemini ( çift yönlü veri bağlama ) gerçekleştirir. Bu directive kullanıldığı html elemanının (genelde ) davranışını, ilgili model değerini ekranda göstererek ve değişikliklerini de component sınıflarına ileterek gerçekleştirir.

ngModel)]=”hero.name”>

Angular directive lerine örnek olarak , layout yapısını değiştiren ngSwitch , ve DOM görünümlerini değiştiren ngStyle ve ngClass örnek verilebilir.

Siz de tabii ki kendi directive lerinizi geliştirebilirsiniz.

Services


Service sınıfları uygulama ihtiyaçlarına göre value , function ya da feature ları saklayan işlemleri bir arada tutarlar. Kend içlerinde uygulama ihtiyaçlarına göre kategorize edilmelidirler.

Dolayısı ile herhangi bir class service olarak kullanılabilir. Özel bir takım işleri yapan metodların bir arada tutulmasını sağlayabilir.

Aşağıda bazı service örnekleri bulunmaktadır.

  • Logging service
  • data service
  • message bus
  • tax calculator
  • application configuration

Angular içerisinde service sınıfları ile ilgili özel bir durum bulunmamaktadır. Angular içinde herhangi bir tanım yapmanıza da gerek yoktur . ( Register etmek gibi )

Serviceleri en çok tüketen bileşenler componentlerdir.

aşağıdaki örnek bir loglama servisi bulunmaktadır.

services-example

Bir diğer örnek olarak da HeroService sınıfını gösterebiliriz, Hero bilgilerini çekmek üzere tasarlanmıştır. BackendService ve Logger service lere ihtiyaç duyar.

services-example2

Service sınıfları heryerde olabilirler.

Component sınıfları aslında temel olarak template in kontrolünü sağlamakla görevlidir ve daha basit tasarlanmalıdır. İçerisinde sadece ön yüz etkileşimlerini ve özelliklerini saklamalıdır. Diğer tüm işleri ilgili service lere delegate etmelidir. ( serverdan veri almak, loglamak , kullanıcı girdilerini doğrulamak vs )

Angular bu prensiplere sadık kalmanız için sizi zorlamaz ya da geliştirme sırasında hata vermez , 300 satırlık bir component de geliştirseniz bu teknik olarak derlenir ve çalışır. Ama best practiceleri konuşursak bazı prensiplere uymak proje geliştirme süreçlerimizin daha başarılı olmasını sağlayacaktır. Bu aslında hangi ortam ve dille uygulama geliştirdiğinizden bağımsız , çok katmanlı mimari prensipleri ile anlatılmış pratiklerdir.

Dependency Injection


Service

Dependency Injection bir classın yeni bir instance ını tüm bağımlılıkları ile birlikte oluşturulmasının bir yöntemidir. Genelde bağımlılıkları service sınıfları olarak düşünebiliriz. Angular yeni componentler tanımlarken onları hangi sınıflara ihtiyacı olduklarını da belirlediğimiz bir bağımlılık yönetimi sağlar.

Angular içerisinde yaratılmış bir component sınıfınının constructer metoduna baktığımız zaman , bu componentin hangi tip bileşenlere ihtiyacı olduğunu anlayabiliriz.

Örnek olarak aşağıdaki HeroListComponent sınıfına bakalım ve HeroService ihtiyacını inceleyelim.

constructor(private service: HeroService) { }

Angular bu componenti yaratmadan önce kendi core yapısındaki injector poolundan ilgili tip servis sınıfını almaya çalışır.

Injector havuzu uygulama akışında daha önce yaratılmış olan instance ları saklar. Eğer istenen service havuzda bulunmuyorsa yenisi yaratılarak havuza eklenir. Tüm bağımlı serviceler yaratıldıktan sonra da ilgili component yaratılmış olur.

HeroService injection işlemi aşağıdaki resimle açıklamaya çalışalım.

Service

Yukarıdaki resime baktığımızda component sınıfı HeroService sınıfına ihtiyacı olduğunu bildirmiş ( constructer ile ) , peki injector havuzunda ilgili service yoksa yenisi nasıl yaratılacak ?

Eğer x bir service in injector havuzda otomatik yaratılabilmesini istiyorsak , bu sınıfı provider lar içerisinde tanımlamamız gerekmektedir.  Provider tanımlamaları module bazında ya da component bazında yapılabilir , eğer module içerisinde ilgili service tanımlanmış ise , bu service sınıfını inject edecek olan tüm classlar aynı service instance ile çalışacaklardır. Eğer ilgili service component seviyesinde inject ediliyorsa da bu component her yaratildiğinda da bu service sınıfından yeni bir instance yaratılacak demektir.

Dependency Injection için unutmamanız gerekenler:

  • Dependency injection Angular Framework bağımlıdır ve heryerde kullanılabilir.
  • Ana parçası Injector havuzudur ve
    • Daha önce yaratılmış serviclerı saklar.
    • Providerlar tarafından belirtilmiş service sınıflarının yenisini yaratabilir.
  • Provider ilgili servisin nasıl yaratılacağını belirtir.

Özet

Bu makale ile temel 8 yapı taşı hakkında bilgi sahibi oldunuz

  • Modules
  • Components
  • Templates
  • Metadata
  • Data binding
  • Directives
  • Services
  • Dependency injection

Angular konseptine güzel bir giriş ve temel bilgiler açısından düşünebiliriz. Tabii ki daha fazla bilgiye ihtiyacımız olacak.

Aşağıdaki alfabetik sıra ile bazı önemli Angular özelliklerini ve servislerini görebilirsiniz. Bu bileşenlerin hepsi için ileride ayrı makaleler yayınlayacağız.

Animations :

Component davranışlarını animasyon tekniklerini derinlemesine bilmeden, angular animation library sayesinde düzenleyebilirsiniz.

Change Detection:

Bu kategoride , anguların property değişikliklerini, ekran güncellemelerini , asenkron iletişim ile veri güncelleme işlemlerini açıklayacağız. Bu stratejiler hakkında bilgiler vereceğiz.

Events:

Burada ise event yönetiminin nasıl yapılacağı , yeni eventlerin nasıl publish edileceği ya da var olan eventin nasıl subscribe edildiğini öğreneceğiz.

Forms :

Karmaşık verilerin ekrandan nasıl alındığı , HTML tabanlı validasyon , dirty checking yapısı ( ekrandaki değerin modele yapışmadan doğrulanması ve gerekiyorsa veriyi değiştirmeden ekrana geri gönderilmesi gibi işler ) anlatılacaktır.

HTTP :

Server tarafı ile nasıl iletişime geçileceği , veri almak , göndermek , server taraflı iş mantıkları çalıştırmak gibi işleri bu dökümanla açıklamaya çalışacağız.

Lifecycle Hooks :

Component lerin yaşam döngülerini, yaşam döngülerini yöneten interface leri implement ederek nasıl müdahele ettiğimizden bahsedeceğiz.

Pipes :

Template ler içerisinde gösterilen verilerin formatlanmaları için kulanılan pipe yapısından bahsedeğiz. Aşağıda para formatlama örneği var :

price | currency: ‘USD’:true

böylece model tarafındaki price değeri 42.33 iken , ekranda ilgili pipe dönüşümünden dolayı $42.33 şeklinde bir gösterim olacaktır. bunu tarih formalamada , telefon numarası formatlamada da kullanabilirdik.

Router :

Sayfalar arasında gezinme ve parametre taşıma gibi konuları bu dökümanda işleyeceğiz.

Testing :

Birim testlerinin nasıl koşturulacağını ve Angular Testing Platform hakkındaki bilgileri de burada paylaşıyor olacağız

Kaynaklar:

angular guide

 

Tags: ,

5 Replies to “Angular2 / Mimariye Genel Bakış”

  1. Elinize sağlık çok güzel bir yazı olmuş. Devamını dört gözle bekliyoruz.

    1. Teşekkürler. Fırsat buldukça devam edeceğiz.

  2. congrats !

  3. çok güzel bir yazı olmuş bora. eline sağlık. devamını bekliyoruz artık 🙂

  4. Güzel ve sade anlatım olmuş elinize sağlık

Bir cevap yazın