24 Kasım 2019 Pazar

Angular Çalışma Notlarımdan - 3 (ileri konular)

     S.A. Arkadaşlar,
     Bugün Angular çalışma notlarımdan toparladığım 3. ve serinin son yazısına gelmiş bulunmaktayız. Daha önce Type Script ve ng generate yapıları adlı 2 blog yayımlamıştık. Bugün de ele alacağımız konular ise routers, pwa, universal, bootstrapping, http client, depency injection, RxJS, ivy ve web worker olacaktır.

     Routers: Angular'da bir sayfadan diğer birine gitmeyi sağlayan yapıdır. Bunu yapmanın birden fazla yolu vardır. Direkt olarak adres çubuğuna girerek, butonlara tıklayarak ya da ileri geri işlemleri buna birer örnektir. Önceki yazımızda spa uyguamalarının bazı dezavantajları olduğundan bahsetmiştik. Bunlardan biri de seo yönetimidir, fakat Angular bunu da site içi url yönlendirmeleriyle çözmektedir.  Bunu aşağıdaki kod örneği ile daha rahat anlaşılacağı kanaatindeyim.
const appRoutes: Routes = [
  { path: 'crisis-center', component: CrisisListComponent },
  { path: 'heroes', component: HeroListComponent, data: { title: 'Heroes List' } },
  { path: '', redirectTo: '/heroes', pathMatch: 'full'},
  { path: '**', component: PageNotFoundComponent }
];

    path gidilecek sayfadır. component ise o url için çağrılacak component ismidir. Belirlenen path bulunamazsa redirectTo ile tekrar /hereos (belirlenen sayfaya) gider patchMatch 'full' özelliği ise yazılan adresin ile belirtilen path'in birebir aynı olmasına bakar. Tüm bunlarda hata oluşması halinde ise sayfa bulunamadı component'ine gitmektedir (PageNotFoundComponent).

     Progressive Web App (PWA): Mobil tarayıcılar üzerinden uygulamadaki rahatlığı almayı hedefleyen yaklaşımdır. Belki daha önce rastlamış olabilirsiniz. Bir siteye girdiğinizde uygulamanın kısa yolunu ana ekrana koymanızı ister. Daha sonra uygulamaya veya tarayıcıya ihtiyaç olmaksızın siteye erişilebilir. Ayrıca çevrim içi uygulamaya girildiğinde bunu belleğe alır, daha sonra çevrim dışı olsanız dahi bu şekilde bellekteki veriye erişebilirsiniz. Angular'ın resmi dokümantasyonunu bu şekilde okuyorum :) Daha ayrıntılı incelemek isterseniz daha önce okuduğum bu yazıyı incelemenizi öneririm.

    Angular Universal (Server Side Rendering): Normal bir Angular uygulaması kullanıcı isteklerini tarayıcıda cevaplar. Universal ise sunucuyu ayağa kaldırır, statik sayfalar oluşturarak istemciye döner. Bu, sayfanın daha hızlı açılmasına olanak sağlar. Kullanıcı bu sayede tüm sayfanın yüklemesini beklemez. Eğer bu şekilde yapılan istekler beklenmiş olsaydık API'den gelen cevapları beklemiş olacaktık ve google seo işlemlerimizi sekteye uğratacaktı. SPA'nin dinamik derlenmesi böyle bir dezavantaja sebep oluyor. Bu problemi, universal ile tüm içeriği derleyip HTML'i gönderir ve seo'ya uygun bir yapı oluşmasını sağlar. Universal yapısı oluşturmak için aşağıdaki kodu kullanabilirsiniz.
ng add @nguniversal/express-engine --clientProject angular.io-example

   Bootstrapping: NgModel uygulamaların birbiriyle nasıl iyi çalışacağını tanımlar. Her uygulama en az bir modüle sahiptir. Ana (root) modül hangi uygulamanın ilk olarak çalışacağını tanımlar. Bu da genellikle AppModule olur. Aşağıdaki örnek kodu inceleyebilirsiniz.
@NgModule({
  declarations: [],//kendi component'lerimizi tanımlarız.
  imports: [],//dışarıdan eklenen component'leri tanımlarız.
  providers: [],//global servisleri tanımlarız.
  bootstrap: [AppComponent] //uygulamanın hangi component'ten başlayacağını belirtir.
})
export class AppModule { }

    HTTP Client: Front end uygulamaları back end ile en fazla http protokolü üzerinden iletişim kurarlar. API'ler vesilesiyle get, post, put, delete ve diğer bir çok işlemi yapabiliriz. Verinin asıl alındığı yer olması açısından önemli bir yapıdır. Angular'ın önceki sürümlerinde http kullanılırken daha sonra http client kullanılmaya başlanmıştır. Aşağıda get ile veriyi nasıl aldığımızı görüyoruz. Bu işlem en basit anlamında böyledir. Fonksiyonlarımız genellikle servis içerisinde tanımlarız. Çünkü aynı metodu farklı yerlerden çağırmak isteyebiliriz. Bu işlemin tamamlanabilmesi için "subscribe" olması lazım. Component içerisinde fonksiyonu çağırıp bu işlemi subscribe ile bitiririz.
//service
getConfig() {
  return this.http.get<Config>(this.configUrl);//Config her hangi bir modeldir.
}
//component
showConfig() {
  this.configService.getConfig()
    .subscribe((data: Config) => this.config = { ...data });
}

    Depency Injetion (DI): Önemli bir design pattern'dir. Bir çok programlama dilinde dışarıdan entegre edilirken, Angular'ın kendi bünyesinde yer alır. Bu şekilde modüllerin birbirine olan bağımlılığını azaltırken (bağımlılık yönetebilme işi kolaylaşır aslında) verimi de artırır. Bir işlemi yaparken başka bir sınıf veya servise ihtiyaç duyarsınız ve böylece o sınıf veya servise bağımlı olursunuz. Zamanla bu bağımlılıklar artar ve yönetilemez hale gelebilir. Her hangi bir değişiklik yapmak istediğinizde tüm servis ve sınıfları değiştirmek zorunda kalırsınız, fakat DI sayesinde objeye dışarıdan enjekte eder, böylece bağımlılık yöneltilebilir hale gelmektedir. Biraz daha kendi anladığım haliyle, sınıftan her defasında nesne oluşturmak yerine bir yerde nesne(instance) oluşturuyoruz ve her yerde kullanırız. Bunu kullanmak isteyen diğer sınıf veya servisler bunu oluşturacaksa önceden oluşturulduğu için direkt olarak kullanmaya başlayabilirler. Bu oldukça uzun bir yazının konusu olabilir. Angular ile ilgili olmasa da Tarık Güney'in bu yazısına göz atmanızı tavsiye ederim. İleride bu konuların her birini ayrıntılı olarak ele almayı da düşünüyorum. Bu da benim için güzel bir hedef olarak burada kalsın :)

   RxJS (Reactive Extensions for JavaScript): Reactive programlama veri akışı ve değişimleriyle ilgili senkron bir paradigmadır. RxJS ise reactive programlama kullanarak bu işleri kolaylaştıran bir kütüphanedir. Observable yapının implementasyonunu sağlamakla birlikte, observable yapının oluşumu ve çalışmasını da sağlar. Bunun bazı faydaları aşağıdaki gibidir.
  • Var olan kodları asenkron olarak değiştirme
  • Stream içindeki değerleri yineleme
  • Farklı tipleri eşleştirme
  • Stream'leri filtreleme
  • Birden fazla akış oluşturma  
// Promise ile observable oluşturma
const data = 'api';
// asenkron sonuç için dinleme(subscribe) başlanıyor
data.subscribe({
  next(response) { console.log(response); },
  error(err) { console.error('Error: ' + err); },
  complete() { console.log('Completed'); }
});

    Ivy: Angular 8 ile gelen bir render motorudur. Angular 9 ile daha kararlı hale gelmesi beklenmektedir. Sanal(Virtual) DOM yapısından, artırılmış(Incremental) DOM yapısına geçişi sağlar. Bunu yapmalarının başlıca amacı mobil uygulamalarda daha iyi performans göstermek. Bunu da paket(bundle) boyutu ve bellek yönetimi ile halledecekler. Ivy'den beklenen bazı özellikler ise aşağıdaki gibidir:
  • Run time'de daha kolay oluşturulan ve okunan kod
  • Daha hızlı build alma
  • Geliştirilmiş şablon tip kontrolü
  • Eski sürümler ile mükemmel uyumluluk
  Ivy yapısı projelerinizde kullanmak için ise aşağıdaki kodu kullanabilirsiniz.
ng new shiny-ivy-app --enable-ivy

   Web Worker: Arka planda farklı thread'lar açarak kullanıcının farklı ekranlarda yapılan iş süresince donmayı engeller. Yapılan işler sonucu ekranın donduğunu anladığınızda web worker'leri kullanabilirsiniz. Uygulamanın her hangi bir yerine ekleyebilirsiniz. Bu yapıyı kullanmak için
worker.ts
addEventListener('message', ({ data }) => {
  const response = `worker'in cevabı: ${data}`;
  postMessage(response);
});
//component.ts -> worker.ts çağrıldığı servis
if (typeof Worker !== 'undefined') {
  const worker = new Worker('./worker', { type: 'module' });
  worker.onmessage = ({ data }) => {
    console.log(`alınan mesaj: ${data}`);
  };
  worker.postMessage('merhaba');
} else {
  // Web Worker desteklenmemektedir.
}

     Başta da söylediğimiz gibi 3 yazılık serimizin sonuna gelmiş bulunmaktayız. Angular'a başlarken kendime aldığım notları bazı ekleme ve çıkarmalar yaparak paylaşmak istedim. Hem bilenlerin bazı kavramları bir arada bulacağı hem de bilmeyenlere bir temel olması temennisiyle paylaştım. Sürçü lisan olduysa affola.

    Kullandığımız kütüphane, çatı ve programlama dillerinin alt yapılarına hakim olmak dileğiyle.
 
Kaynakça
[1] https://www.gencayyildiz.com/blog/angular-4-routing-mekanizmasi/
[2] https://angular.io/guide/router
[3] https://angular.io/guide/universal
[4] https://angular.io/guide/bootstrapping
[5] https://angular.io/guide/http
[6] https://angular.io/guide/dependency-injection
[7] https://angular.io/guide/rx-library
[8] https://blog.angular.io/a-plan-for-version-8-0-and-ivy-b3318dfc19f7
[9] https://blog.nrwl.io/understanding-angular-ivy-incremental-dom-and-virtual-dom-243be844bf36
[10] https://angular.io/guide/web-worker

2 yorum: