[筆記] TypeScript不在的那幾天:Angular 2與JavaScript一起的日子

NO IMAGE

♦️♦️TypeScript不在的那幾天:Angular 2與JavaScript一起的日子,是否基情滿滿呢。偷笑

♦️♦️這幾天,專案上在思考將一批App從純jQuery轉化到Angular。

♦️♦️個人還是偏向使用純jQuery,Angular畢竟封裝的東西太多,會導致不可控因素太多。雖然以前寫過Angular 1.x,也一直覺得Angular開發起來比較快很適合做prototype,但一直映像裡就是笨重的東西。對於Angular 2,看了看幾個檔案,沒有壓縮前的程式碼有5MB!越來越笨重!再加上Rx框架,慘不忍睹。不過,還好壓縮後600KB,但這麼大的體積,真的不適合輕量級web
app。

♦️♦️再準備償個鮮,結果發現官方文件的例子都是TypeScript寫的,JS那邊的文件就僅限於CheatSheet了。前端這變來變去,今天來個微軟的試驗品TypeScript,明天又是Google的試驗品AtScript和Dart,偶爾當當小白鼠就這樣吧。不過根據Angular 1.x的經驗,說到從jQuery直接轉化到Angular,第一步,只要給element加個Controller其他都呼叫原有的jQuery就可以了嘛,然後再一步一步轉化。結果是Controller在Angular
2已經被幹掉了。

♦️♦️對於快速Spike,用TypeScript當然沒啥,不過寫ts檔案又是一個3MB的TypeScript解析器要引用。算了算了,還是放逐下TypeScript,快速給出demo還是直接用JavaScript吧。順帶理解一下Angular 2的構造和TypeScript到JavaScript的編譯過程。

♦️♦️那就到網上搜一搜,其實教程蠻多的,這是比較好的一篇:http://blog.thoughtram.io/angular/2015/07/06/even-better-es5-code-for-angular-2.html

♦️♦️有了TypeScript到JavaScript的大概知識,就開始寫程式碼吧(jsdille上執行結果如下):Angular 2 Without TypeScript

♦️♦️這裡就實現一個文字框輸入css顏色值,輸入的時候對應的div顏色就會改變。其中包括了:1 一個Directive包含另一個Directive;2 通過Attribute傳遞資料到Directive裡;3 Directive使用一個外部Service。整理出來就特別簡單了,中間還是不少坑的,結合Angular Cheat Sheet:https://angular.io/docs/js/latest/cheatsheet.html。

簡單總結就是:

♦️♦️1 一個Directive包含另一個Directive,這沒有什麼難點,直接在template裡寫就好。

♦️♦️2 通過Attribute傳遞資料到Directive裡的要點就是申明ng.core.Component的時候的inputs選項,填好就可以用this訪問了。

♦️♦️3 Directive使用一個外部Service,和Angular 1.x很像,用一個array在constructor那裡注入吧,注入後就可以很開心的使用了。至於更高階的功能,比如實現Angular 1.x裡的compile功能,其實也不難,直接看Angular 2的原始碼(比如看個簡單的:https://github.com/angular/angular/blob/master/modules/angular2/src/common/directives/ng_if.ts;在ngIf建構函式裡注入了ViewContainerRef和TemplateRef,那照葫蘆畫瓢,在contructor寫個[ng.core.ViewContainerRef,
ng.core.TemplateRef, function (_view, _template) {…}];然後它set ngIf就是ngIf變了就執行createEmbeddedView或者clear,這動態compile就可以出來了。至於更復雜的,大家看看ngFor等的吧。反正連ElementRef都可以有,直接操作DOM還是不難的。)當然,除了intputs選項,還有outputs選項,是為(xxx)用的。

♦️♦️後面還是要開始老老實實寫TypeScript吧,不過demo使用JavaScript輕鬆快捷,也小小了解了一下Angular 2的結構。

<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.35.0/es6-shim.min.js"></script>
<script src="https://npmcdn.com/[email protected]/es6/dev/src/testing/shims_for_IE.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.12/angular2-polyfills.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.12/Rx.umd.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.12/angular2-all.umd.dev.js"></script>
<script>
(function(app) {
function OutsideService() {}
OutsideService.prototype = {
say: function(word) {
return word;
}
};
var shared = {
value: 'additional parameter',
color: 'yellow'
};
app.NestComponent =
ng.core.Component({
providers: [ng.core.ElementRef],
selector: '[nestComponent]',
inputs: ['nestComponent', 'additionalParameter'],
template: '<div>{{color}} - {{additionalParameter.value}}</div>'  
'<select><option *ngFor="#item of items" [value]="item.id">{{item.value}}</option></select>'
})
.Class({
constructor: [ng.core.ElementRef, function(ref) {
this.data = shared;
this.ref = ref;
this.color = null;
this.items = [{
value: 'banana',
id: 1
}, {
value: 'apple',
id: 2
}, {
value: 'pear',
id: 3
}];
// watch on nestComponent value e.g. <div [nestComponent]="data.color"></div>
Object.defineProperty(this, 'nestComponent', {
set: function(val) {
this.color = val;
this.ref.nativeElement.style.backgroundColor = val;
}
});
this.ref.nativeElement.style.backgroundColor = "yellow";
}]
});
app.AppComponent =
ng.core.Component({
selector: 'mainApp',
template: '<div>{{label}} <input [(ngModel)]="data.color" /></div>'  
'<div [nestComponent]="data.color" [additionalParameter]="data">Loading...</div>',
directives: [app.NestComponent],
providers: [OutsideService]
})
.Class({
constructor: [OutsideService, function(service) {
this.data = shared;
this.label = service.say("Color:");
}]
});
document.addEventListener('DOMContentLoaded', function() {
ng.platform.browser.bootstrap(app.AppComponent);
});
})(window.app || (window.app = {}));
</script>
<mainApp>Loading...</mainApp>
</body>