AngularJS 2 Nedir?
Selamlar arkadaşlar,
Bu makale ile başlıyarak AngularJS 2 javascript framework’ünü detyalı olarak incelemeye başlıyacağız. Uygulama ortamı Visual Studio Code olacaktır. Ayrıca TypeScript kullanılacaktır. Size kolaylık olaması amacı ile makalenin sonundaki ekte bulunan paket, visual studio code ile açılarak, AngularJS2 için gerekli uygulama platformu sağlanmış olunur. İlgili paketlerden biri de “typescript-watcher“‘dır. Amacı ilgili script dosyalarında bir değişiklik olduğu zaman, bunu algılayıp Html sayfanın otomatik olarak render edilmesini sağlamaktır. Böylece yapılan her değişiklik sonucu anlık olarak gözlemlenebilecektir. Kısacası yazılan her koddan sonra refresh yapılmayacaktır:)
Laboratuvar Ortamının Hazırlanması:
- Öncelikle makinanıza NodeJs ‘i yandaki link’den kurunuz: https://nodejs.org/en/download/
- Visual Studio Code’u yandaki linkden kurunuz: https://code.visualstudio.com/Download
- Command Prompta “npm install -g typescript” yazarak typescript kurunuz. Command Prompt’u administrator modunda açmayı unutmayınız.
- Command Prompta “npm install -g typings” yazarak typing‘i kurunuz.
- AngularJS2’yi ilerde npm ile indirebileceğiz. Yandaki komutlar ile proje oluşturup, yayımlayabileceğiz. “npm install -g angular-cli“, “ng new project_name“, “ng server” . Ama bu ortam şu anda yok. Bunu için sayfanın sonundaki “angular2-project” dosyasını açıp makinanıza koyun. Daha sonra command propmt’da ilgili klasör içine girip, “code .” komutunu yazınız. Visual Studio Code projeyi altta görüldüğü gibi açılacaktır. Böylece siz de bir çok dosyayı indirme zahmetden kurtulacaksınız. Aşağıda görüldüğü gibi uygulama start olduğu anda “tsc:w” yani typescript watch ve “lite” server çalıştırılmaktadır. Ben Mac’de uygulamayı yayımlamak için lite server kullandım.
- Ayrıca dependencies yani bağlı olunan paketler, uygulama ilk çalıştırılacağı zaman ilgili ana klasör altına gelinip “npm install” yazılarak indirilmelidir. Bu işlemden sonra projenin içinde “node-modules” klasörü otomatik oluşur. İlgili dosyalar burdan da görülebilir.
- Son olarak “code .” komutu yazılarak Visual Studio Code açılır. Bu konu ile ilgili detaylı bilgiyi önceki makalemin içindeki bölümden erişebilirsiniz.
Şimdi sıra geldi AngularJS2’yi tanımaya: app/app.component.ts tıklandığında aşağıdaki kodlara erişilir.
app/app.component.ts: Aşağıda görüldüğü gibi typescript’ler ile çalışacağız. Uzantıları “.ts”‘dir. Bunla ilgili detaylı bilgiyi önceki makalemden erişebilirsiniz.
1 2 3 4 5 6 7 |
import {Component} from 'angular2/core'; @Component({ selector: 'my-app', template: '<h1>Bora Kaşmer ile Angular 2 JS e Hoş Geldiniz!</h1>' }) export class AppComponent { } |
“npm start” yazılıp tsc:w ve lite server başlatılarak aşağıdaki gibi bir browser sayfasına erişilir. Bazen lite server bozulabiliyor. Bu durumda “Ctrl + C” ve ardından “npm start” yaparak uygulamayı tekrardan ayağa kaldırınız.
Öncelikle AngularJS2’de kullanılan temel kavramları inceleyelim.
Component : AngularJS2 içerisinde kullanılacak tüm htmller, modeller, servisler Component altında tanımlanır. Bir çeşit angularJS1’in controller’ı diyebiliriz. Öncelikle root bir component tanımlanır. Ayrıca istenir ise altında onlarca farklı component da tanımlanabilir.
Yukarıdaki örneğe bakıldığında :
- import {Component} ile “angular2/core” yolundan Component kütüpahanesi sayfaya include edilir.
- @Component({ .. }) ilgili Root Component tanımlanır.
- selector : Kullanılacak angular2 objesinin adıdır. Index.html sayfasını tıklarsanız aşağıdaki gibi bir kod ile karşılaşılır. Görüldüğü gibi ilgili component index.html’de aşağıdaki gibi çağrılmıştır.
- template: Sayfa basılacak Html burada tanımlanır.
- export class AppComponent sınıfı ile ilgili model ve methodlar burada tanımlanır. Yani angularJS’deki Controller’a karşılık gelir. Tüm angularJS2’ye ait tüm nesneler burada tanımlıdır.
index.html:
1 2 3 |
<body> <my-app>Yükleniyor...</my-app> </body> |
Şimdi Component’ı öğrendiğimize göre gelin Lessons adında dersler component’ımızı geliştirelim:
App folder sağ tıklanıp yeni bir file yanda görüldüğü gibi eklenir. “app/lessons.component.ts”
app/lessons.component.ts:
1 2 3 4 5 6 7 8 9 10 |
import {Component} from 'angular2/core' @Component({ selector:'lesson', template:'<h2> Dersler</h2>' }) export class LessonsComponent{ } |
Aşağıda görüldüğü gibi root component’ımız olan AppCompenent’a gelip yazılan bu Lessons component’ı ekleyelim. “@Component({})” function’ı aşağıda görüldüğü gibi 3 parametre almaktadır “selector”, “template” ve “directives”.
app/app.component.ts:
- Aşağıda görüldüğü gibi “@Component({})” function’ına directives parametresi eklenip yeni yazılan “[LessonsComponent]” eklenmiştir.
- Ayrıca yeni eklenen bu component’ın local adresi “import” keywordü ile birlikte sayfada belirtilmelidir.
- Daha sonra ilgili “component” “template” içinde “selector” ismi ile örneğin aşağıda “<lesson>”</lesson>” olarak kullanılmış ve Dersler yazısı ekrana basılmıştır..
Directives : Component’a yeni bir component directives parametresi ile eklenir. Aşağıdaki örnek angularJS1’den bildiğiniz Element Directive’den başka birşey değildir.
1 2 3 4 5 6 7 8 |
import {Component} from 'angular2/core'; import {LessonsComponent} from './lessons.component' @Component({ selector: 'my-app', template: '<h1>Bora Kaşmer ile Angular 2 App</h1><lesson></lesson>', directives:[LessonsComponent] }) export class AppComponent { } |
Şimdi sıra geldi modeller ile çalışmaya.
lessons.component.ts:
- İlgili “LessonsComponenet” sınıfına time property’si eklenir. Ve sınıfın constructer’ında o anki zaman atanır. Daha sonra ilgili “LocalTime” property’si “@Component({})“‘ın “template:“‘inde {{LocalTime}} bu süslü parentezlere Interpolation diyoruz. Bunların arasında ilgili sınıfın özellikleri ekrana basılır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
import {Component} from 'angular2/core' @Component({ selector:'lesson', template:`<h2> Dersler</h2> Son Güncellenme Zamanı:{{LocalTime}} <ul> <li *ngFor="#course of courses"> {{ course.name }} : {{ course.hours }} saatlik eğitim. </li> <ul> ` }) export class LessonsComponent{ private time : string; public get LocalTime() : string { return this.time; } public set LocalTime(v : string) { this.time = v; } constructor(){ var d = new Date(); this.LocalTime= d.toLocaleString(); } public courses = [ { name: 'C#', hours: 600 }, { name: 'Mvc', hours: 200 }, { name: 'AngularJs 2', hours: 150 } ]; } |
Interpolationlar ile tek yönlü yani one way binding işlemi yapılır. Yani model ile view arasında bir bağlantı oluşturulur. İlgili model değişince view’da değişir. Ama view’da olan değişiklik model’i etkilemez. Örnek Textbox içine model değiştikçe yazılan yazı değişirken, Textbox içindeki yazı elle değiştirildiği zaman, model değişmeyecektir.
- İlgili component’a “courses” adında bir dizi nesnesi yaratılmış ve “name” ve “hourse” propertlerine değerler atanmıştır. Daha sonra ilgili template içine aşağıdaki kod yazılarak tüm kurslar tek tek gezilerek bilgileri ekrana basılmıştır. Burada dikkat edilmesi gereken husus “*” işaretinin anlamı ilgili directive’in istenen elemtin içinde kullanılabileceği anlamına gelmektedir. Örneğin “ngFor” sadece “<template>” içinde kullanılabilmektedir. Ayrıca “#” <template> içinde local bir değişken tanımlamak için kullanılmaktadır.
*ngFor=”#course of courses”
Ekran Çıktısı:
Services: Şimdi gelin, yukarıda çektiğimiz bu kurs bilgilerini gerçek hayatta olduğu gibi bir servisten alıp Component’ımıza ekleyelim.
app/course.service.ts: course.service adında yeni bir dosya aşağıdaki gibi yaratılır ve lessons.components’daki course dizisi silinip buraya “takeAllCourse()” methodu altına konur.
1 2 3 4 5 6 7 8 9 |
export class CourseService{ takeAllCourses(){ return [ { name: 'C#', hours: 600 }, { name: 'Mvc', hours: 200 }, { name: 'AngularJs 2', hours: 150 } ]; } } |
Şimdi sıra gelid ilgili bu servisi “LessonsComponent”‘a eklemeye:
lessons.componenet.ts:
- Öncelikle ilgili “[CourseServices]” import ile sayfaya include edilir.
- @Component({}) function’ına ilgili servis “providers” keyword’ü ile eklenir. Böylece angular2, ilgili servisi render zamanında anlamlandırabilir.
providers:[CourseService]
- LessonsComponenet classında ilgili “CourseService” sınıfı “new()” keyword’ü ile yaratılmadan, “Constructer’ında” “courseService:CourseService()” şeklinde ilgili değişkene atanmıştır.
- “courseService.takeAllCourses()” şeklinde ilgili servisin methodu çağrılarak, “course” değişkeni doldurulmuştur. Ekran çıktısı yine aynıdır.
lessons.componenet.ts:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
import {Component} from 'angular2/core' import {CourseService} from './course.service' @Component({ selector:'lesson', template:`<h2> Dersler</h2> Son Güncellenme Zamanı:{{LocalTime}} <ul> <li *ngFor="#course of courses"> {{ course.name }} : {{ course.hours }} saatlik eğitim. </li> <ul> `, providers:[CourseService] }) export class LessonsComponent{ private time : string; public get LocalTime() : string { return this.time; } public set LocalTime(v : string) { this.time = v; } courses; constructor(courserService: CourseService){ var d = new Date(); this.LocalTime= d.toLocaleString(); this.courses=courserService.takeAllCourses(); } } |
Template : 2 çeşit template vardır. Bir tanesi sayfa içerisine doğrudan string olarak yazılan HTML. Diğeri de url verilerek sayfa içerisine konan başka html sayfadır. Bunu da “templateUrl” olarak “@Componenet()” içerisinde tanımlamaktayız. Örneğin aşağıda “@Component()” function’ı içinde template parametresi içine “`” karakterleri arasında çoklu satır olarak inline html yazılabilir. Eğer uzun bir html kod yazılmayacak ise performance amacı ile bu yöntem tercih edilmelidir.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import {Component} from 'angular2/core'; @Component({ selector: 'my-app', template:` <b>Adınız :<div><input type='text'></div> <b>Soyadınız: <div><input type='text'> <input type='button' value='Gönder'/></div> ` }) export class AppComponent{ } |
Ya da aşağıdaki gibi “templateUrl” kullanılarak, harici “person.html” sayfasına, request çekilerek ana sayfaya yüklenir. Burdan çıkarılacak ders, gerçekten ihtiyaç yok ise, performans amaçlı her zaman inline HTML code tercih edilmelidir. Nedeni aşağıda görüldüğü gibi sayfanın ilk çağrıldığında “person.html” sayfasına ilk sefer için request çekilip yüklenmesidir. İlgili browserın network’ü incelendiğinde 200 Ok Code’u alındığı görülür. Ancak ana sayfanın 2.kere çağrılması durumunda, harici “person.html” tekrardan yüklenmez ve 304 Not Modifed code’u alınır. Kısaca sadece ilk sefer yüklenir. Sayfada değişiklik olmadığı sürece bir daha harici sayfalar yüklenmez.
1 2 3 4 5 6 7 8 9 |
import {Component} from 'angular2/core'; @Component({ selector: 'my-app', templateUrl:'app/person.html' }) export class AppComponent{ } |
person.html: Harici bir sayfaya çıkarılan html codelar aşağıdaki gibidir. Bu şekilde çalışmanın en büyük faydası, ilgili html kodun başka yerlerde de kullanılabilmesidir. Böylece ilgili html kodun tekrar tekrar yazılması engellenmiş olunur.
1 2 |
<b>Adınız :<div><input type='text'></div> <b>Soyadınız: <div><input type='text'> <input type='button' value='Gönder'/></div> |
Directives 2 (Dependency Incejtion):
Bu makalenin son örneğinde gelin yeni bir Directive yaratalım. Sayfamıza yeni bir TextBox koyacağız. Ve üzerine geldiğinde genişlemesini ve ayrıldığımızda da tekrar eski halini almasını sağlayacağız. Yazılacak bu Directive’i ilgili TextBox’a attribute olarak ekleyeceğiz ve istenilen özellikleri TextBox’ımıza kazandırmış olacağız. Bu AngularJS1’den bildiğiniz Attribute Directive olacak.
grow-onfocus.directive: TextBox’ımızın methodlarının ve eventlerinin tanımlanacağı sınıf burasıdır.
- Bu bir directive’dir. Bundan dolayı import {Directive} eklenmiştir. {ElementRef} ile o andaki sayfa üzerindeki nesneye erişmek için kullanılan bir sınıftır. {Renderer} sayfa üzerindeki HtmlElement’in style’ını değiştirmek için kullanılan bir sınıftır.
- @Driective({}) ile “selector” yani sayfada kullanılacak attribute tanımlanır.
- “host” ile üzerine gelecek eventlerde çağrılacak methodlar belirlenir.
- (focus): Bir event tanımıdır. ‘onFocus()’ ise üzerine odaklanılınca çağrılacak methoddur.
- (blur): Bir event tanımıdır. ‘onBlur()’ ise üzerinden ayrılınca çağrılacak methoddur.
- GrowOnfocusDirective eventinin constructer’ında “ElementRef ve Renderer” ilgili değişkenlere atanır.
- onFocus() ve onBlur() methodlarında ilgili attribute şeklinde attachlenen TextBox’ın css’i, “this.renderer.setElementStyle” şeklinde atanmakta ve ilgili HtmlElement’e yani textbox’a “this.el.nativeElement” şeklinde erişilmektedir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import {Directive,ElementRef,Renderer} from 'angular2/core' @Directive({ selector:'[growonFocus]', host:{ '(focus)':'onFocus()', '(blur)':'onBlur()' } }) export class GrowOnfocusDirective{ constructor(private el: ElementRef, private renderer:Renderer) { } onFocus(){ this.renderer.setElementStyle(this.el.nativeElement,'width','400'); } onBlur(){ this.renderer.setElementStyle(this.el.nativeElement,'width','150'); } } |
lessons.componenet.ts: İlgili texbox aşağıdaki gibi eklenir. Ve önceden tanımlanan “GrowOnfocusDirective” directive’i HtmlElemnt’e attribute olarak aşağıdaki gibi eklenir.
- Öncelikle “import” ile ilgili directive’in dosyası (GrowOnfocusDirective) sayfaya include edilir.
- @Component({}) function’ına “directives” parametresi ile [GrowOnfocusDirective] directive’i eklenerek render zamanında algılanması sağlanır.
- Sayfa üzerindeki texbox’a “<input type=”text” growonFocus style=”width:120px”/>” ilgili directive solda görüldüğü gibi attribute olarak eklenmiştir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
import {Component} from 'angular2/core' import {CourseService} from './course.service' import {GrowOnfocusDirective} from './grow-onfocus.directive' @Component({ selector:'lesson', template:`<h2> Dersler</h2> Son Güncellenme Zamanı:{{LocalTime}} <div><b> Yeni Kurs:</b></div> <div> <input type="text" growonFocus style="width:120px"/></div> <ul> <li *ngFor="#course of courses"> {{ course.name }} : {{ course.hours }} saatlik eğitim. </li> <ul> `, providers:[CourseService], directives:[GrowOnfocusDirective] }) export class LessonsComponent{ private time : string; public get LocalTime() : string { return this.time; } public set LocalTime(v : string) { this.time = v; } courses; constructor(courserService: CourseService){ var d = new Date(); this.LocalTime= d.toLocaleString(); this.courses=courserService.takeAllCourses(); } } |
Böylece bir makalenin daha sonuna geldik. AngularJS2 makalelerinin devamında görüşmek üzere hoşçakalın.
Source Code: http://www.borakasmer.com/projects/angular2_project.rar
Kaynaklar : https://angular.io/, https://egghead.io, Mosh Hamedani(Angular 2 with TypeScript for Beginners The Pragmatic Guide) …
command prompt ekranından code komutunu çalıştırdıktan sonra ekran boş geliyor dosyaları görmüyor nerden kaynaklanıyor acaba ?
Selam Ferdi,
Öncelikle ekteki dosyayı Örnek: “c:/angular2” folder’ına koydun diyelim. Command prompt’da “package.json” dosyasının olduğu yere kadar gelmen gerek.Bu örnekden devam eder isek Command propmt’da “cd angular2/angular2-seed” yazıp ilgili dosyaların olduğu yere gelmen ve “code .” komutunu orda yazman gerekmektedir. Bu arada ilgili paketleri console’dan indirmek için “npm install” komutunu yazmayı unutma.
İyi çalışmalar.
Hocam öncelikle merhaba. Belki çok kolay bir hatadır ama konu hakkında pek bir bilgim yok sizin blogunuzda başladım bu arada çok yararlı bir blogunuz var teşekkürler. Ancak ben command promptta şöyle bir hata alıyorum ilgilenirseniz müteşekkir olurum.
http://i.hizliresim.com/o79Epo.jpg
Teşekkürler Burak;
Neyse ki sorun basit:) Hemen cevaplıyım:
Command Prompta ekteki koyduğun dosyanın yoluna kadar gelip orada “npm install” demelisin.
Örneğin ekteki dosyayı Örnek: “c:/angular2” folder’ına koydun diyelim. Command prompt’da “package.json” dosyasının olduğu yere kadar gelmen gerek.Bu örnekden devam eder isek Command propmt’da “cd angular2/angular2-seed” yazıp ilgili dosyaların olduğu yere gelmen ve “code .” komutunu orda yazman gerekmektedir. Bu arada ilgili paketleri console’dan indirmek için “npm install” komutunu yazmayı unutma.
İyi çalışmalar.
VSCode’da böyle problemler oluyor sanırım. Path’de olmasına rağmen node’u da görmüyordu, debug için de benzer bir hata almıştım.
http://stackoverflow.com/a/30494169/413032
Selamlar,
Valla ben bayadır çalışıyorum. Yani bahsettiğiniz gibi bir hata almadım. Pek alan çevremde kimse de olmadı.
Aslında gönderdiğiniz makale de 1 sene öncesine ait. Belki o zamanlar olabilir.
İyi çalışmalar.
Abi Angular 2 ile pek türkçe makale yok.Sende gerçekten çok iyi anlatmışsın.Sizce geleceğin teknolojisi olabilir mi? PHP kadar popüler olabilir mi ? Teşekkürler makale için devamlarını bekliyoruz.
Teşekkürler;
Evet ben gelecekte Angular2’nin baya bir söz sahibi olucağını düşünüyorum. Zaten boş yere bu kadar makale yazılır mı:)
İyi çalışmalar…
Yine doyurucu bir yazı olmuş 1 gün boyunca didik didik inceledim, örnekler yaptım. Fakat hocam müsadeniz varsa bir konuda sıkıntımı dile getirmek istiyorum, belki diğer arkadaşlar da aynı durumdan muzdariptir. Derslerinizde ağırlıklı olarak pratiklerle örneklerle konuyu pekiştiriyorsunuz, kendimden örnek verecek olursam, ben bir konuyu öğrenirken a dan z ye neyin neden yazıldığını ne işe yaradığını bilmek istiyorum. Bazen diyorum ki, keşke biraz daha teori kısmında da yazılan yazılar olsaymış diye.
Ellerinize sağlık hocam :) Ben ikinci derse geçeyim.
Teşekkürler Mustafa,
Belki biraz daha Action adamı olmamdan kaynaklanıyor:) Daha fazla teori konusuna gelince kesinlikle dikkate alacağım. Aslında kitap yazılır ise daha mantıklı olur gibime geldi :)
İyi akşamlar.
Merhaba hocam bir türlü çözemediğim bi sorunum vardır büyük ihtimal kolaydır.,
yardımlarınız bekliyorum Kolay gelsin
http://i.hizliresim.com/bkvZ1Y.jpg
Anlatim icin cok tesekkurler. Ben Angular’a yeni baslayan bir C# gelistiricisiyim ve her tutorial’i elden geciriyorum. Bir sey eklemem gerekiyor sanirim buraya gelip calisan arkadaslara da yardimi dokunur diye dusunuyorum. directives, Component’ten cikartilmis ve onun yerine entryComponents kullanilmasini onermisler Stackoverflow’da (https://stackoverflow.com/questions/39517822/cant-add-a-new-component-to-my-angular-2-app-with-typescript).
Simdi gidip videolarinizi da izleyeyim :)
Merhabalar
Son lessons component’i ekleyip çalıştırdıktan sonra hatalar alıyorum. Hatalar ise cannot find file ‘promise’ ve cannot find file ‘Map’ bu hataları nasıl çözebilirim.stackoverflow dan da baktım ordaki çözümleri de denedim olmadı. Siz daha önce böyle hatayla karşılaştınız mı nasıl çözüleceği konusunda bilginiz var mı??
Angular2 hakında bu kadar anlaşılır bir kaynak oluşturduğunuz için teşekkür ederim.
Selamlar Aysenur,
Evet sorun projende “rxjs” dosyası yok. Ayrıca
import "rxjs/add/operator/map"
veimport 'rxjs/add/operator/toPromise'
şeklindedosyaları eklemelisin.
İyi çalışmalar.
Merhabalar
Burdakileri aynen yapmama rağmen LessonComponent’inda bulunan kodlar browserda göstermiyor. Ne yapabilirim?
Selamlar,
Browser’ın console kısmında yazan hatayı bana iletmen, sana daha çok yardım edebilmemi sağlıyacaktır.
Büyük ihtimalle
satırında courses datası dolmuyıp boş geliyordur.
İyi çalışmalar.