[关闭]
@alexhuang 2016-09-14T02:58:16.000000Z 字数 5839 阅读 1596

TypeScript & Angular2.0

技术笔记 TypeScript Angular Sonic


认识TypeScript

TypeScript 和 JavaScript.
任意js都是合法的TypeScript

  1. interface Animal {
  2. name: string;
  3. age: number;
  4. locality?: string;
  5. }
  6. // 类型定义时用 ':' 和 ';' key:value; 的形式
  7. // 而在export component或者module时候,用key = value;的形式
  8. // 在创建实体对象时用{key:value,key2:value2}的形式
  9. function f(x: Animal) {
  10. return x.name;
  11. }
  12. var n:string = f({name: 'Benj', age: 3});
  13. // typeScript 有函数缺省参数检测
  14. function createVM(os:string, version: number,
  15. hasFloopy: bool =false,
  16. FileName: string = hasFloopy? 'BOOT.ING': null {
  17. setName(os + version.toString());
  18. if (FileName) {
  19. load(FileName);
  20. }
  21. }
  22. // 完全长得像C# 。typescript有点像以C# 的方式来写JS,最终编译为原生 JavaScript
  23. // 并且上面这段代码在编译之后会变为带 参数检测的。undefined 表示有declare,但没有赋值的变量
  24. if (typeof hasFloopy === 'undefined') {
  25. hasFloopy = false;
  26. }
  27. if (typeof FileName === 'undefinded') {
  28. // ....
  29. }

Arrow记号作为匿名函数的快捷方式,节省代码,并且可以避免this指向的错误。在没有箭头符号之前,可采用var that = this; 的办法正确指向。

  1. // 和ES6类似的Arrow. 使用回调函数的场合,容易犯错的是this的作用域。
  2. var tickIncreaser = {
  3. tick: 0,
  4. increase: function() {
  5. window.onclick = (e) => {
  6. alert((this.tick++).toString());
  7. }
  8. }
  9. }
  10. // 以上Script经过编译后
  11. //...
  12. increase: function () {
  13. // 将上下文环境保留在_this 变量中。
  14. var _this = this;
  15. window.onclick = function (e) {
  16. alert((_this.tick++).toString))
  17. }
  18. }
  19. //..
  20. /* 构造函数 */
  21. class Human {
  22. constructor(public name:string, public age:number){
  23. static baseSalary = 1500;
  24. static baseAge = 18;
  25. }
  26. printSalary(){
  27. var salary = this.age < 18 ? 0: Human.baseSalary + this.age - (Human.baseAge) * 200;
  28. alert('Salary of' + this.name + 'is ' + salary.toString());
  29. }
  30. }
  31. var h1 = new Human('jack', 20);
  32. var h2 = new Human('ross', 17);
  33. h1.printSalary();
  34. h2.printSalary();
  35. // class 是立即执行函数, 等效于 var Human = (function(){...})() 这个在《JS设计模式和编程实践》中有讲到.
  36. // TypeScript 符合ES6的标准,支持存取器。
  37. get Salary(){
  38. return salary;
  39. }
  40. h1.getSalary() // 可以获取salary属性

可以看到TypeScript 很类似于静态语言,有类型检测等特性。并且实现了ES6的许多特性,包括export,class,Arrow匿名函数等等。实现了模块化的管理方式,更加方便重构(refactor).

Angular2.0

关于版本和核心组件

Angular2 还处于快速更新中,所以版本存在不稳定。2016年8月最新版核心组件@angular/core的版本号是rc.5. 比上一版本新增了 ngModule 核心组件,管理declaration等等。 并且@angular/router也有所更新,rc.1,包含了RouteModule等关键组件。

根组件(app.component)和根模块(app.module),一个web应用至少需要一个根组件和一个根模块。根组件包含路由,服务!在root层面注册服务和路由singleton,使得子组件都可以用到同样的服务和路由。

根模块注册了declaration,并导入了可选模块:form, router 等等。

创建组件

几个关键词:

import { Component } from '@angular/core';

@Component({
selector: '',
styles:,
templates:
})

export class yourComponent {
title=;
//...
}

根据单一职责原则 一个数据模型或者组件的职责应该是单一的,这样才可以实现非耦合,方便组件化。
创建一个自定义component需要 IMport,装饰器,以及export为自定义组件。三个基本部分。
template synTax:

  1. // onSelect() come from export function
  2. // [(ngModel)]='selectedHero.name' two-way-binding.
  3. // properties we used in the templates come from the exported component!
  4. @Component({
  5. templates:`
  6. <li *ngFor='let hero of heroes'
  7. [class.selected]='hero === selectedHero'
  8. (click)='onSelect(hero)'
  9. <div *ngIf='selectedHero'>
  10. <input [(ngModel)]='selectedHero.name'>
  11. `
  12. })

多个组件之间的消息传递

Separating the Component:
to connect two component ,and implement the variable share. property bind is required.
For instance: selectedHero comes from the user operation, and change the property of appComponent(list). how to pass the selected hero to the detailComponent?!

@Input 装饰目标变量,表明这个变量的值由外部传入

  1. /* use @Input to annotate the hero to be Input property.
  2. * receive value from other Component.
  3. */
  4. export class HeroDetailComponent {
  5. @Input()
  6. hero: Hero;
  7. // present the property "hero" is type Hero;
  8. }
  9. // 在source组件中赋值
  10. // 在source中注册 directive
  11. @Component({
  12. templates:`
  13. <target [hero]='selectedHero'></target>
  14. `
  15. directives: [target组件类名];
  16. })

@Injectable 装饰可注入的对象,一般表明service可注入组件

  1. // 整个服务是可用于注入的。
  2. @Injectable()
  3. export class HeroService {
  4. getHeroes() {
  5. return Promise.resolve(HEROES);
  6. }
  7. getHeroesSlowly() {
  8. return new Promise<Hero[]>(resolve =>
  9. setTimeout(() => resolve(HEROES), 2000)
  10. );
  11. }
  12. }
  13. // 在调用服务的组件中注册providers
  14. providers: [HeroService]
  15. export class ** implements OnInit {
  16. // 在构造函数中实例化服务
  17. constructor(private heroService: HeroService) {
  18. }
  19. getHeroes() {
  20. this.heroService.getHeroes().then(heroes => {});
  21. }
  22. ngOnInit() {
  23. this.getHeroes();
  24. }
  25. }

搭建Angular开发环境

Angular开发环境

创建项目文件夹,定义包的依赖以及特别的项目设置

创建根组件(AppComponent)
创建一个Angular模块 ?? (不一定需要)
添加main.ts 配置组件信息

  1. import { bootstrap } from '@angular/platform-browser-dynamic';
  2. import { AppComponent } from './app.component';
  3. bootstrap(AppComponent);

添加index.html, 宿主页面. 可用import导入模块

  1. <html>
  2. <head>
  3. <title>Angular 2 QuickStart</title>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1">
  6. <link rel="stylesheet" href="styles.css">
  7. <!-- 1. Load libraries -->
  8. <!-- Polyfill(s) for older browsers -->
  9. <script src="node_modules/core-js/client/shim.min.js"></script>
  10. <script src="node_modules/zone.js/dist/zone.js"></script>
  11. <script src="node_modules/reflect-metadata/Reflect.js"></script>
  12. <script src="node_modules/systemjs/dist/system.src.js"></script>
  13. <!-- 2. Configure SystemJS -->
  14. <script src="systemjs.config.js"></script>
  15. <script>
  16. System.import('app').catch(function(err){ console.error(err); });
  17. </script>
  18. </head>
  19. <!-- 3. Display the application -->
  20. <body>
  21. <my-app>Loading...</my-app>
  22. <!-- When Angular calls the bootstrap function in main.ts,
  23. it reads the AppComponent metadata, finds the my-app selector,
  24. locates an element tag named my-app, and renders our application's
  25. view between those tags. -->
  26. </body>
  27. </html>

添加main.ts配置组件信息

  1. import { bootstrap } from '@angular/platform-browser-dynamic';
  2. import { HeroesComponent } from './heroes.component';
  3. bootstrap(HeroesComponent);
  4. // 以上是main.ts, 设定了 根组件的位置,并启动根组件。
  5. // Systemjs.config.js
  6. (function(global) {
  7. // packages tells the System loader how to load when no filename and/or no extension
  8. var packages = {
  9. 'app': { main: 'main.js', defaultExtension: 'js' },
  10. 'rxjs': { defaultExtension: 'js' },
  11. 'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' },
  12. };
  13. })

在index.html中 import('app') 实际上启动的是 main.js 中的命令,追溯到其中,其实执行的是 bootstrap(HeroesComponent); 启动了整个应用的root组件,或者路由器!!

  1. // 而在index.html中引入的systemjs.config.js中
  2. <script src="systemjs.config.js"></script>
  3. <script>
  4. System.import('app').catch(function(err){ console.error(err); });
  5. </script>
  6. <!-- 3. Display the application -->
  7. <body>
  8. <my-heroes>Loading...</my-heroes>
  9. </body>

构建并运行应用(因为typescript可以开启watch transpile 模式,所以文件修改后自动编译为原生js,在页面中可看到修改结果)

基于Phantomjs的Karma测试环境

由于phantomjs经常安装不上,则采用替换镜像的方法。

npm install phantomjs --registry=https://registry.npm.taobao.org

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注