13 January 2014

今天花了一點時間開始嘗試 AngularDart。AngularDart 是 Dart 版的 AngularJs,一樣也是 Google 在背後支持。兩者雖然共用類似的概念,但其實差異很多,一方面是因為 Dart 是不同的語言,二方面 AngularDart 是個全新專案,Augular Team 有機會重新再發明一次輪子。某方面來說 AngularDart 會走在 Js 版的前頭,而未來 Dart 版的部份功能也會移植回 Js 版。

MVC

AngularDart 使用 MVC 的概念,view 端就是純 html template,加上一些 ng 的 tag 和 directive 而 MC 則是用 Dart 寫。馬上看一段程式碼就知道了:

<div recipe-book>
  <ul ng-repeat="recipe in ctrl.recipes" >
    <li ng-click="ctrl.onSelect(recipe)">
    {{recipe.name}}
    </li>
....    
@NgController(
    selector: '[recipe-book]',
    publishAs: 'ctrl')
class RecipeBookController {

  List<Recipe> recipes;

  void onSelect(Recipe selected) {
     //...
  }
}

一邊是 view 另一個是 Dart controller,兩者之間靠 html 的 attribute recipe-book,以及 annotation @NgController 串起來。而 ng-repeat 和 ng-click 這兩個 directive 也很單純,就 recipes 的 for loop,以及 click 後呼叫 controller.onSelect()。相當的直覺,沒兩下就學會了。而且不單如此,你還免費得到 two-way binding -- 就是 controller 修改時,view 會直接變更,反之亦然。

我沒有辦法在一篇短文深入介紹,不過 AngularDart 的核心概念就是類似上面,只是純 html 加上 annotation,更進階的元件像是 NgComponent 和 NgDirective 都是如此。

I like it!

文件

沒有!
沒---------有!

一個龐大的 Framework,現在只有一個未完成的 tutorial 可以看,這實在是太慘了。我們第一天開發就四處撞牆,很多時候都只能看原始碼瞎猜,網路上可以 google 到的都是 AngularJs 的。怎麼上傳檔案?Model 怎麼在 Controller 間互傳?怎麼手動 route view ? 都沒有答案!

現階段 AngularDart 還在 Beta 階段 (0.9.3版),文件缺乏情有可原,只能說我們太早用了,也許再過個二個月就好了吧。

I hate it!

似曾相似

我寫了幾個 Angular Controller 後,發現這一切都是那麼的似曾相似。那些自定的 ng tag 就是以前的 jsp tag,而 ng controller 就是 Struts controller,而 scope 則有點像 server 的 http session;它的 route 則像 servlet dispatch。換湯不換藥,差別僅在於這一次 Angular 全部都在 Browser 上。

我有點感嘆,一方面是現代化的 client framework,其實跟十年前沒什麼兩樣,沒什麼突顯的改變。另一方面則是感嘆自己太老了,如果我年輕個十歲看到 Angular ,大概會又跳又叫,大嘆這是個非常漂亮的發明。

I feel old.

Dependency Injection

AngularDart 還有一部份是 Dependency Injection,這是它的核心,我相信這是為了更好測試性而設計的。跟 AngularJs 不同的是它是 wired by Type ,這是因為 Dart 有 Class,也有 Reflection (稱做 Mirror) 可用。

class MyAppModule extends Module {
  MyAppModule() {
    type(RecipeBookController);
    type(QueryService);
    //....
  }
}

上面這簡單的程式碼註冊 RecipeBookController 和 QueryService 這兩個 class,AngularDart 會負責建立這兩個物件,並且使用建構子插入依賴的物件。

在純 Dart 環境下,Mirror 讓我們省了很多工夫 (不用做 code generation)。不過別忘了,現在 Dart 只能部署成 Javascript 在 browser 上跑,對純 Dart 的程式來說部署很容易,但是 AngularDart 需要 超級無敵麻煩的流程。而且很容易出錯,對,是最討厭的那種,在執行期才出錯。

Ahhuh! don't inject Js to me. It hurts

Polymer.dart vs AngularDart

現在 Dart 有兩個元件庫,一個是 polymer.dart,另一個就是今天談的。Dart team 是主推 Polymer 的,而 AngularDart 的存在只是因為 Google 裡有人想在 Dart 用 Angular 而已。兩者似乎互搶資源,但其實同個語言平台有多個 framework 是很正常的事。

我在試 AngularDart 之前,大約是兩週前吧,先試了 polymer.dart,我試了一天就放棄,它的錯誤還是太多了。原因是它走的太前面了,HTML5 Template、Shadow DOM 和 Polymer Expression 等等新到連 Browser 都還在開發階段。如果說 AngularDart 在 Beta,那 polymer.dart 就是 Alpha。現階段我會選相對成熟的 Angular。

當然 AngularDart 比 polymer.dart 還要大很多,它是個全套的 framework,在上面開發 App 會比較快。不過未來 Angular 會導入更多 polymer 的功能,畢竟 polymer 會是 Browser 的標準。話說回來 AngularDart 的 NgComponent 是用 Shadow DOM 實做的,也是很新。所以,IE8 掰掰啦。

IE, RIP.

一切才剛開始

AngularDart 還沒到 1.0,我們也才剛開始試,還有很多未知數。希望兩個月後我不後悔採用 AngularDart。


回響

可以用 Tag <I>、<B>,程式碼請用 <PRE>