Angular 2与TypeScript概览
迄今為止,在創(chuàng)建Web應(yīng)用方面,AngularJS是當(dāng)前最為流行的JavaScript框架。如今,Angular 2和TypeScript通過一種非常類似于Java 8的語法,使真正面向?qū)ο蟮腤eb開發(fā)成為了主流。
據(jù)Google的工程主管Brad Green介紹,有130萬開發(fā)人員在使用AngularJS并且30萬開發(fā)人員已經(jīng)使用了即將發(fā)布的Angular 2。在使用了Angular 2近十個月后,我相信它對JavaScript社區(qū)的影響就像當(dāng)年Spring框架對Java的影響那樣深遠(yuǎn)。
在本文中,我們將會在宏觀層面上概要闡述Angular 2框架。
在2014年底,Google宣布Angular 2將會對AngularJS進(jìn)行完全地重寫,他們甚至還創(chuàng)建了一門新的語言,名為“AtScript”,他們本來希望使用這門語言來編寫Angular 2應(yīng)用。
但是,隨后Microsoft同意在它們的TypeScript語言(JavaScript的一個嚴(yán)格超集)上添加對裝飾符(decorator,又稱為注解)的支持,所以,它就成為了開發(fā)Angular 2框架本身所使用的語言,并且還是使用AngularJS框架開發(fā)應(yīng)用的推薦語言。
另外,我們還可以使用JavaScript(ECMAScript 5和6均可)和Dart來編寫Angular 2應(yīng)用。
除此之外,Angular團(tuán)隊(duì)還集成了Microsoft的另外一個產(chǎn)品到Angular 2框架之中,這就是反應(yīng)型JavaScript擴(kuò)展(reactive JavaScript extension)的RxJS庫。
Angular 2并不是一個MVC框架,而是基于組件(component)的框架。在Angular 2中,應(yīng)用是松耦合組件所組成的樹。
例如,如下的截屏中展現(xiàn)了一個簡單的在線拍賣應(yīng)用的首頁面,它最初的原型是由一組Navbar、Search、Carousel、Product和Footer組件所構(gòu)成的。
按照上面的圖片所示,我們渲染了三個Product組件。自動渲染是通過將模板與服務(wù)器端獲取到的組件數(shù)組進(jìn)行綁定來完成的。每個產(chǎn)品的名稱都會是一個鏈接,指向相關(guān)產(chǎn)品的詳情頁面。因?yàn)槲覀兿氚堰@個拍賣應(yīng)用設(shè)計(jì)為單頁應(yīng)用(single page application,SPA),所以我們不希望刷新整個頁面來展現(xiàn)產(chǎn)品詳情。我們會重用當(dāng)前輪播(carousel)和產(chǎn)品列表已經(jīng)占據(jù)的區(qū)域,所以它會渲染產(chǎn)品的詳情,同時保持頁面的其他內(nèi)容不變。這項(xiàng)任務(wù)通過幾個簡單的步驟就能完成:
使用Angular的router-outlet指令,它允許我們將當(dāng)前輪播和產(chǎn)品列表占據(jù)的區(qū)域聲明為<router-outlet>,這樣的話,它就能基于用戶的導(dǎo)航變換內(nèi)容;
將Carousel和Product封裝到Home組件中;
創(chuàng)建一個新的ProductDetail組件;
配置Angular的Router在特定的<router-outlet>區(qū)域要么顯示Home組件,要么顯示ProductDetail組件。
關(guān)于組件,我們已經(jīng)討論了很多,但是到目前為止,還沒有對其進(jìn)行定義。在TypeScript中,組件就是帶有@Component的簡單類:
@Component({selector: 'auction-home',template: `HTML或其他標(biāo)記內(nèi)聯(lián)在此處` }) export default class HomeComponent {// 應(yīng)用邏輯放在此處 }@Component注解用來定義組件及其相關(guān)的元數(shù)據(jù)。在本例中,selector屬性的值指明了要展現(xiàn)本組件的HTML標(biāo)簽名稱。template屬性是一個HTML(或其他)標(biāo)記的占位符。
回到我們的拍賣應(yīng)用首頁,頂層ApplicationComponent組件的模板可能會如下所示:
這個模板是由標(biāo)準(zhǔn)的和自定義的HTML標(biāo)簽所組成的,自定義標(biāo)簽代表了對應(yīng)的組件。在本例中,我們使用的是內(nèi)聯(lián)HTML。如果你更喜歡將標(biāo)簽存儲在單獨(dú)的文件中的話(比如在application.html文件中),那么我們將會使用templateURL屬性來代替template,ApplicationComponent的代碼將會看起來如下所示:
import {Component} from 'angular2/core'; import {Route, RouteConfig, RouterOutlet} from 'angular2/router'; import HomeComponent from '../home/home'; import NavbarComponent from '../navbar/navbar'; import FooterComponent from '../footer/footer'; import SearchComponent from '../search/search'; import ProductDetailComponent from "../product-detail/product-detail";@Component({selector: 'auction-application',templateUrl: 'app/components/application/application.html',directives: [RouterOutlet,NavbarComponent,FooterComponent,SearchComponent,HomeComponent] }) @RouteConfig([{path: '/', component: HomeComponent, as: 'Home'},{path: '/products/:id', component: ProductDetailComponent, as: 'ProductDetail'} ]) export default class ApplicationComponent {}ApplicationComponent類使用了@Component和@RouteConfig(對于依賴URL的內(nèi)容)注解。selector屬性的值將會用來指定用戶定義的HTML標(biāo)簽<auction-application>。templateURL屬性指定了標(biāo)記所在的位置。directives區(qū)域包含了RouterOutlet以及所有的子組件。
@RouteConfig注解為客戶端導(dǎo)航配置了兩個route:
對于名為Home的route,其內(nèi)容將會由HomeComponent來渲染,并且映射到了URL片段“/”。
對于名為ProductDetail的route,其內(nèi)容將會由ProductDetailComponent來渲染,并且映射到了URL片段“/product:id”。
當(dāng)用戶點(diǎn)擊一個特定產(chǎn)品的標(biāo)題時,默認(rèn)的Home route的內(nèi)容將會替換為ProductDetail route的內(nèi)容,它會提供參數(shù)id的值并將產(chǎn)品的詳情展現(xiàn)在<router-outlet>區(qū)域。例如,導(dǎo)航至ProductDetail route的鏈接會將產(chǎn)品id的值 1234作為參數(shù),它看起來會如下所示:
<a [routerLink]="['/ProductDetail', {'prodId': 1234}]">{{ product.id }}</a>
依賴注入
組件使用服務(wù)(service)來實(shí)現(xiàn)業(yè)務(wù)邏輯。服務(wù)是由Angular實(shí)例化并注入到組件中的類。
export class ProductService {products: Product[] = [];getProducts(): Array {// 獲取產(chǎn)品的代碼放在這里return products;} }現(xiàn)在,如果在HomeComponent的構(gòu)造器中指定一個ProductService類型的參數(shù),那么將會自動實(shí)例化該服務(wù)并將其注入到組件中:
@Component{... } export default class HomeComponent {products: Product[] = [];constructor(productService: ProductService) {this.products = productService.getProducts();} }Angular的依賴注入模塊是很靈活的,它很易于使用,因?yàn)閷ο笾荒芡ㄟ^構(gòu)造器來實(shí)現(xiàn)注入。注射器(injector)形成了層級的結(jié)構(gòu)(每個組件都會有一個注射器),可注入的對象并不一定必須要在應(yīng)用級別保持單例,不過,這是Spring默認(rèn)的做法。
跨組件通信
組件通信能夠也應(yīng)該按照一種松耦合的方式來實(shí)現(xiàn)。組件可以聲明輸入和輸出屬性。要將數(shù)據(jù)從父組件傳遞到子組件的話,父組件需要將值綁定到子組件的輸入屬性上。子組件不需要關(guān)心誰來提供值,它只需要知道如何處理這些值即可。
如果某個組件需要將數(shù)據(jù)傳遞到外部世界,那么它可以通過輸出屬性發(fā)布事件。將事件發(fā)布給誰呢?這就不是組件的業(yè)務(wù)所要關(guān)心的了。如果對其感興趣的話,可以創(chuàng)建一個針對自定義組件事件的監(jiān)聽器。
這種機(jī)制允許我們將組件視為黑盒,它能夠獲取值或?qū)?shù)據(jù)發(fā)送出來。我最近錄制了一個簡短的視頻,你可能會發(fā)現(xiàn)它有一定的用處,它闡述了在Angular 2中,Mediator設(shè)計(jì)模式的一種實(shí)現(xiàn)。
為何采用TypeScript
TypeScript是JavaScript的超集,但是它類似于Java,允許我們定義新的類型。定義變量的時候會使用類型而不是泛指的var,這就為新工具的支持打開了一道門,你會發(fā)現(xiàn)這些工具將會帶來極大的生產(chǎn)效率提升。TypeScript自帶了一個靜態(tài)代碼分析器,我們還可以在能夠感知TypeScript的IDE(WebStorm/IntelliJ Idea、Visual Studio Code、Sublime Text等)中,直接進(jìn)入到代碼之中,它們能夠基于上下文,為我們提供幫助,會指導(dǎo)我們使用對象中可用的方法或函數(shù)參數(shù)的類型。如果你不小心使用了錯誤的類型,IDE將會高亮顯示錯誤的代碼。你可以參考這里了解WebStorm是如何支持TypeScript的。
即便你的TypeScript應(yīng)用用到了JavaScript編寫的第三方庫,你也可以安裝一個類型定義文件(擴(kuò)展名為.d.ts),這個文件包含了這個庫的類型聲明。針對上百個流行的JavaScript庫的類型定義都可以免費(fèi)獲取,我們能夠使用Typings非常容易地安裝它們,Typings是一個TypeScript的定義管理器(TypeScript Definition Manager)。假設(shè)你想要在TypeScript代碼中使用jQuery(使用JavaScript所編寫的),針對jQuery的類型定義文件將會包含所有jQuery API的聲明(及類型),所以IDE能夠提示可以使用哪些類型,或者高亮顯示有錯誤的代碼。
性能與渲染
渲染性能在Angular 2中得到了充分地提升。最為重要的是,渲染模塊位于一個獨(dú)立的模塊之中,這樣的話,就允許我們將大量計(jì)算(computation-heavy)的代碼在一個worker線程中運(yùn)行。你可以訪問Repaint Rate Challenge Web站點(diǎn)來比較各個框架的渲染性能。對于大數(shù)據(jù)量且數(shù)據(jù)持續(xù)變化的表格,你將會感受到它的渲染是非常迅速的。運(yùn)行名為“DBMON Angular 2.0 Beta - Web Workers”的測試,這是一個大數(shù)據(jù)量的表格并且數(shù)據(jù)會持續(xù)刷新(在一個單獨(dú)的線程中),瀏覽器對它的重繪極其迅速。
如果你要問Angular 2區(qū)別于其他框架的特性是什么的話,在我的列表中第一項(xiàng)就會是這個用于模板渲染的獨(dú)立模塊和zones:
我們將組件的UI聲明在獨(dú)立的模板中,并且會由獨(dú)立的渲染器來進(jìn)行處理,這樣在這方面就有了一個新的機(jī)會,這個機(jī)會所涵蓋的范圍從優(yōu)化和預(yù)編譯模板,到為不同的設(shè)備創(chuàng)建并渲染模板;
模塊zone.js會監(jiān)控應(yīng)用中的變化,并確定在何時更新每個組件的UI。每個組件中UI的重繪都是通過異步事件觸發(fā)的,它運(yùn)行起來會非常快。
注意:
對于大多數(shù)的應(yīng)用來說,你并不需要了解zone.js的內(nèi)部原理,但是,如果你正在為一個復(fù)雜的應(yīng)用進(jìn)行UI渲染的優(yōu)化,那么抽出一點(diǎn)時間研究一下zone的內(nèi)部工作原理對你還是很有好處的。
通過將渲染引擎放到一個單獨(dú)的模塊中,第三方的貢獻(xiàn)者就可以將默認(rèn)的DOM渲染器替換為其他的渲染器,從而用于非基于瀏覽器的平臺。例如,這允許我們跨設(shè)備重用應(yīng)用程序的代碼,針對移動設(shè)備的UI渲染器可以使用原生的組件。TypeScript類的代碼會保持相同,但是@Component注解的內(nèi)容將會包含XML或其他用于渲染原生組件的語言。在NativeScript框架中已經(jīng)實(shí)現(xiàn)了自定義的Angular 2渲染器,該框架可以作為連接JavaScript和原生iOS及Android UI組件的橋梁。借助NativeScript,你可以重用組件的代碼,只需將模板中的HTML替換為XML即可。還有自定義的UI渲染器允許我們將Angular 2與React Native組合在一起使用,它是為iOS和Android創(chuàng)建原生(非混合)UI的另一可選方案。
工具
盡管Angular 2應(yīng)用的語法和架構(gòu)都比AngularJS 1.X容易理解得多,但是它的工具會稍微復(fù)雜一些。這也并不令人驚訝,畢竟我們使用一門語言來編寫代碼,卻需要使用另外一門語言來進(jìn)行部署,因?yàn)樗械膬?nèi)容都需要編譯為JavaScript。
Angular CLI項(xiàng)目目前正在進(jìn)行中,它承諾會提供一個命令行接口,大幅度簡化各種流程,涵蓋的范圍從初始的項(xiàng)目創(chuàng)建到生產(chǎn)環(huán)境的部署。
應(yīng)用調(diào)試可以在IDE中進(jìn)行,也可以在瀏覽器中進(jìn)行。我們使用Chrome Developer Tools來進(jìn)行調(diào)試。所生成的代碼映射能夠讓我們調(diào)試時使用TypeScript代碼,而瀏覽器中運(yùn)行的是JavaScript。如果你更愿意調(diào)試JavaScript的話,這也是可行的,因?yàn)門ypeScript transpiler所生成的JavaScript是適于人類閱讀的。
測試和部署
Angular 2自帶了一個測試庫,它能夠讓我們按照BDD的格式編寫單元測試。目前,它只支持Jasmine框架,不過對其他框架的支持正在實(shí)現(xiàn)之中。我們使用了Karma test runner,它能夠針對各種瀏覽器運(yùn)行測試。
借助Protractor框架,我們能夠?yàn)閼?yīng)用編寫端到端的測試。如果你在開發(fā)模式下,在加載一個簡單應(yīng)用的同時監(jiān)控網(wǎng)絡(luò)的話,你會發(fā)現(xiàn)瀏覽器的下載超過了5Mb(其中的一半是模塊加載器所使用的TypeScript編譯器,SystemJS)。但是運(yùn)行部署和優(yōu)化的腳本(我們使用的是Webpack bundler)之后,小型應(yīng)用的規(guī)模能夠減小到160K(包括Angular 2)框架。我們正在熱切期待Angular CLI會如何實(shí)現(xiàn)生產(chǎn)環(huán)境的打包。Angular團(tuán)隊(duì)在做一個離線模板編譯功能,它能夠?qū)⒖蚣艿拇笮p至50Kb。
UI組件庫
在撰寫本文之時,有多個UI組件庫是可以和Angular 2應(yīng)用組合在一起使用的:
PrimeNG——由PrimeFaces(與JavaServer Faces框架協(xié)同使用的一個流行的庫)的創(chuàng)建者所維護(hù)的一個Angular 2 UI組件庫;
Wijmo 5——一個商業(yè)的Angular 2 UI組件庫,必須要購買開發(fā)者許可證才能使用它;
Polymer——Google所提供的一個外觀漂亮且可擴(kuò)展的組件庫。在我們公司中,我們使用Polymer組件創(chuàng)建過一個實(shí)驗(yàn)性的Angular 2應(yīng)用,但是它們兩者的集成還有提升的空間;
Material Design 2——Google專門為Angular 2所開發(fā)的UI組件庫。目前,這個庫處于早期的Alpha版,但是開發(fā)狀態(tài)非常活躍,在未來的三四個月中,我期待能夠看到十幾個設(shè)計(jì)良好的UI組件;
NG-Lightning——一個Angular 2的組件和指令庫,它是使用TypeScript和Lightning Design System CSS框架完全從頭編寫的。
現(xiàn)在,使用Angular 2安全嗎?
在Farata Systems,我們從第一個Beta釋放版本就將Angular 2到了實(shí)際的項(xiàng)目之中,在這個過程中并沒有遇到嚴(yán)重的問題,至少沒有遇到過找不到解決方法的問題。
如果你希望更安全的話,那么可以再等幾個月。據(jù)說,Angular 2的發(fā)布候選版本將會在2016年5月份的Google I/O會議上發(fā)布。(在ng-conf 2016召開前夕,Angular 2已經(jīng)發(fā)布了候選版本。——譯者注)
將來會怎樣呢?
在2016年3月O’Reilly舉辦的Fluent會議上,Brad Green做了一個keynote演講,可以觀看該演講的視頻。你被感染到了嗎?反正我是被感染了。
關(guān)于作者
Yakov Fain住在紐約,他是一位Java Champion,并且是IT咨詢公司Farata Systems的合伙人。他領(lǐng)導(dǎo)著Princeton JUG,寫過很多關(guān)于軟件開發(fā)的文章以及多本圖書。最近,他與別人合著了《Angular 2 Development with TypeScript》,這本書將會在2016年6月由Manning出版。Yakov經(jīng)常在技術(shù)會議上演講,并且參與講授Java和Angular 2。他的博客是yakovfain.com。
原文地址:http://www.infoq.com/cn/articles/Angular2-TypeScript-High-Level-Overview
.NET社區(qū)新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關(guān)注
總結(jié)
以上是生活随笔為你收集整理的Angular 2与TypeScript概览的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 开源,新的平台之战
- 下一篇: 使用 Autofac 进行依赖注入