# TypeScript & Angular2.0 笔记(1)


认识TypeScript

TypeScript 和 JavaScript 联系和区别,当时读到一篇文章,觉得很有意思。关键内容摘抄一下。
文章中的观点主要有,任意js都是合法的TypeScript,TypeScript 符合es6 标准,最关键还有强制类型检测。

interface Animal {
    name: string;
    age: number;
    locality?: string; // 可选属性
}
// 类型定义时用interface 关键字, a: type; 的形式
// 与interface 主要用于数据结构定义不同,class 主要用于定义类,业务逻辑

function f(x: Animal) {
    return x.name;
}

var n:string = f({name: 'Benj', age: 3});

// typeScript 有函数缺省参数检测
function createVM(os:string, version: number,
    hasFloopy: bool =false,
    FileName: string = hasFloopy? 'BOOT.ING': null {
    setName(os + version.toString());
    if (FileName) {
        load(FileName);
    }
}
// 完全长得像C# 。typescript有点像以C# 的方式来写JS,最终编译为原生 JavaScript
// 并且上面这段代码在编译之后会变为带 参数检测的。undefined 表示有declare,但没有赋值的变量
if (typeof hasFloopy === 'undefined') {
    hasFloopy = false;
}
if (typeof FileName === 'undefinded') {
    // ....
}

Arrow记号作为匿名函数的快捷方式,节省代码,并且可以避免this指向的错误。

// 和ES6类似的Arrow. 使用回调函数的场合,容易犯错的是this的作用域。
var tickIncreaser = {
    tick: 0,
    increase: function() {
        window.onclick = (e) => {
            alert((this.tick++).toString());
        }
    }
}
// 以上Script经过编译后
//...
   increase: function () {
        // 将上下文环境保留在_this 变量中。
        var _this = this;
        window.onclick = function (e) {
            alert((_this.tick++).toString))
        }
    }
//..

/* 构造函数 */
class Human {
    constructor(public name:string, public age:number){
        static baseSalary = 1500;
        static baseAge = 18;
    }
    printSalary(){
        var salary = this.age < 18 ? 0: Human.baseSalary + this.age - (Human.baseAge) * 200;
        alert('Salary of' + this.name + 'is ' + salary.toString());
    }
}

var h1 = new Human('jack', 20);
var h2 = new Human('ross', 17);
h1.printSalary();
h2.printSalary();

// class 是立即执行函数, 等效于 var Human = (function(){...})() 这个在《JS设计模式和编程实践》中有讲到. 

// TypeScript 符合ES6的标准,支持存取器。
get Salary(){
    return salary;
}

h1.getSalary() // 可以获取salary属性

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

Angular2.0

关于版本和核心组件

直到2016年8月,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 其他模块,装饰器修饰当前组件,定义组件的具体功能

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

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

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

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

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

多个组件之间的消息传递

其实原生的JavaScript 中可以通过全局变量或者函数调用的参数中来传递消息,那么在Angular框架中这个问题就演变为了组件之间的参数传递了。包括父组件和子组件,同级组件之间的参数传递。除了下文提到的@Input,@Injectable 这些方式,还可以通过Angular中EventEmitter 类来自定义事件,将某一组件中的事件发布给订阅其消息的任意组件。详细情况可以参考第二篇笔记。

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

/* use @Input to annotate the hero to be Input property.
 * receive value from other Component.
 */
export class HeroDetailComponent {
    @Input()
    hero: Hero;
    // present the property "hero" is type Hero;
}

// 在source组件中赋值
// 在source中注册 directive
@Component({
    templates:`
        <target [hero]='selectedHero'></target>
    `
    directives: [target组件类名];
})

@Injectable 装饰可注入的对象

// 整个服务是可用于注入的。
@Injectable()
export class HeroService {
    getHeroes() {
        return Promise.resolve(HEROES);
    }
    getHeroesSlowly() {
        return new Promise<Hero[]>(resolve => 
            setTimeout(() => resolve(HEROES), 2000)
        );
    }
}

// 在调用服务的组件@Component装饰器中注册providers
providers: [HeroService]

export class ** implements OnInit {
    // 在构造函数中实例化服务
    constructor(private heroService: HeroService) {
    }
    getHeroes() {
           this.heroService.getHeroes().then(heroes => {});
    }
    ngOnInit() {
        this.getHeroes();
    }
}

搭建Angular开发环境

Angular开发环境

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

  • package.json
  • tsconfig.json (ts编译器配置文件)

创建根组件(AppComponent),这个组件的template中包含路由

// AppComponent.ts
@component{
    template: `
    <h1>{{title}}</h1>
    <nav>
    <a routerLink="/heroes" routerLinkActive="active" > Heroes </a>
    <router-outlet></router-outlet>
    `
}
export class AppComponent {
    title: 'Tour of Angular2.0'
}

然后创建根模块(AppModule) 并且添加main.ts 配置组件信息

// update! since Angular2.0 stable, changed bootstrap function
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app.module';

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

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

<html>
  <head>
    <title>Angular 2 QuickStart</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="styles.css">
    <!-- 1. Load libraries -->
     <!-- Polyfill(s) for older browsers -->
    <script src="node_modules/core-js/client/shim.min.js"></script>
    <script src="node_modules/zone.js/dist/zone.js"></script>
    <script src="node_modules/reflect-metadata/Reflect.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>
    <!-- 2. Configure SystemJS -->
    <script src="systemjs.config.js"></script>
    <script>
      System.import('app').catch(function(err){ console.error(err); });
    </script>
  </head>
  <!-- 3. Display the application -->
  <body>
    <my-app>Loading...</my-app>

    <!-- When Angular calls the bootstrap function in main.ts,
     it reads the AppComponent metadata, finds the my-app selector,
      locates an element tag named my-app, and renders our application's
       view between those tags.  -->
  </body>
</html>


// Systemjs.config.js
(function(global) {
  // packages tells the System loader how to load when no filename and/or no extension
    packages: {
      app: {
        main: './main.js',
        defaultExtension: 'js'
      },
      rxjs: {
        defaultExtension: 'js'
      },
      'angular2-in-memory-web-api': {
        main: './index.js',
        defaultExtension: 'js'
      }
    }
})

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

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

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

基于Phantomjs的Karma测试环境

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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容

  • Angular 2架构总览 - 简书http://www.jianshu.com/p/aeb11061b82c A...
    葡萄喃喃呓语阅读 1,483评论 2 13
  • Angular 2 是一个用 HTML 和 JavaScript 或者一个可以编译成 JavaScript 的语言...
    赵然228阅读 663评论 1 4
  • 版本:Angular 5.0.0-alpha AngularDart(本文档中我们通常简称 Angular ) 是...
    soojade阅读 825评论 0 4
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,637评论 18 139
  • 一个人,在阳光炙热的午后看这部片子,身边的空调吹出冷冷的气流,我在一个下午,看完了别人的半个人生,然后,在别人的...
    陶陶892290阅读 265评论 0 0