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上运行结果如下):
这里就实现一个文本框输入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/angular2@2.0.0-beta.12/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>