七周七种前端框架三: Angular2 印象

原创 2015年11月21日 15:14:28

巨大变化

在 Angular1 中最重要的两个概念:

  1. directive 拓展DOM功能,封装DOM操作,并且是可复用的组件
  2. controller 创建新的 $scope 作用域,封装和DOM无关的业务逻辑

Angular2 是一次彻底的重写,完全删掉了 Controller 和 $scope,增加了一个重要的功能叫 @Component,Component 是Angular2的核心,相当于Angular1 中 Directive 和 Controller 的合体。
并且 directive 功能简化, 和 Angular1 中的 Directive 完全不可以相提并论。

Angular2 用 TypeScript 写的,TypeScript 可以简单理解为 ES6 + Annotation + 强类型。

不过注意截止到今天(2015-11-20) angular2依然是Alpha 版本,也就是说API 还不稳定,还有很多bug,一些功能也没有完全实现。所以Beta版本出来之前不建议生产环境使用。

Angular 2 的一个Component 是这样的:

import {Component, bootstrap} from 'angular2/angular2';
@Component({
  selector: 'my-app',
  template: `
    <h1>{{title}}</h1>
    <h2>My favorite hero is: {{myHero}}</h2>
    `
})
export class AppComponent {
  title = 'Tour of Heroes';
  myHero = 'Windstorm';
}
bootstrap(AppComponent);

其中 @Component 是一个annotation,Java中有一个类似的翻译为注解。

上面是一个基本的Angular2 Component。分为这几部分:

  1. import 需要使用的模块
  2. 创建了一个Component,一个Component由注解和类两部分组成。@Component 是对 AppComponent 的一个注解,可以理解为对AppComponent的一个配置,声明了这个类是一个Component,并且对他做了一些配置。
  3. 引导这个Component。其实就是在html中找到对应的选择器并创建和绑定一个实力。

Component

Angular2 中把一块逻辑封装成一个 Component 类。 Component即负责渲染模板和监听事件,也封装业务逻辑。

一个 Component 由两部分组成:

  1. @Component 注解,这里声明了很多配置项,比如: selector, template, directives, styles, pipes 等。
  2. 一个普通的类,这个类封装了Component的所有业务逻辑,比如事件回调,数据处理等。

前面有写过ES6的博客,Annotation并不是ES6规范的一部分,但是ES7中的 decorator 其实和 Annotation应该是同一个东西,都是decorator模式。关于ES7的decorator参见这里 https://github.com/wycats/javascript-decorators/blob/master/README.md

虽然 directive 和 Angular1 中的有很大不同,但是基本的一些内置directive除了写法变了基本还是大同小异的,在模板中的用法也基本不变,比如这个循环:

 <ul>
  <li *ng-for="#hero of heroes">
    {{ hero }}
  </li>
</ul>

不过Angular2严格的模块化组织代码,所以用到任何功能都需要先 import:

 import {Component, bootstrap, NgFor} from 'angular2/angular2';

并且然后还需要在 注解中声明才可以用。

Angular2 提供了 常见的 NgFor, NgIf 等流程控制directive。双向绑定的directive 还是叫 NgModel ,它属于Form的一部分,Angular2还是专门对form做了很多工作。

DI 依赖注入

依赖注入分两部分,一个是提供,一个是使用。
在Angular2 中通过 @Injectable 来声明一个可以被注入的模块:

@Injectable()
class HeroService {
  heroes: Hero[];
  constructor(private logger: Logger) {
    this.heroes = HEROES;
  }
  getHeroes() {
    this.logger.log('Getting heroes ...')
    return this.heroes;
  }
}

这样我们就提供了一个 可以被注入的模块

使用的时候 会稍微麻烦一些,使用的时候分两步。第一步是在自己的Component的构造函数中声明要注入的模块:

constructor(heroService: HeroService) {
  this.heroes = heroService.getHeroes();
}

这里根据参数的类型申明就知道需要注入的模块叫 HeroService

第二步比较奇怪一点,就是要声明一个provider。也就是说上面的代码中的 HeroSerivce 我们需要声明是谁提供了它。可能会有人有疑问了,我们不是最开始的时候定义了一个 HeroService 了嘛,为毛还要再声明一次。

这其实是为了灵活性考虑,我们提供了一个 HeroService ,然后在 Component 中又声明了需要注入一个叫 HeroService 的模块。但是注意,其实HeroService 只是一种实现而已,我们完全可以有多种方式来实现 HeroServive。比如我们测试的时候可能希望注入一个 MockHeroService,总不能在测试的时候改掉我们 Component的构造函数吧,最方便的就是我们在测试的时候申明 MockHeroService 就是Component 需要的 HeroService。

基于这个原因,我们需要声明一个 provider 来提供 HeroService 服务。这个声明是放在这里的:

bootstrap(AppComponent, [HeroService]);

奇怪了,不是没有什么provider吗。其实这是一个简写,[HeroService] 等价于 [provide(HeroService, {useClass:HeroService})]; 也就是默认用同名的类来提供。

注意 useClass,表示从这个类创建一个新的实例,不过这个实例是单例的。 也可以不用创建,直接给一个值,这个时候要用 useValue.

Pipe

Pipe 是一个数据处理管道。主要作用就是对数据输出的时候进行一些格式化处理。一个基本的date 管道的用法如下:

 <p>The hero's birthday is {{ birthday | date:"MM/dd/yy" }} /p>

其中 竖线是调用管道的语法,date是管道名字,后面的字符串是传入的参数。因为是管道,所以可以把多个管道连接起来:

 The chained hero's birthday is  {{ birthday | date | uppercase}}

我们可以自定义pipe。一个自定义的pipe的作用就是接受一个输入值和参数,然后返回一个处理后的值。

import {Pipe} from 'angular2/angular2';
/*
 * Raise the value exponentially
 * Takes an exponent argument that defaults to 1.
 * Usage:
 *   value | exponentialStrength:exponent
 * Example:
 *   {{ 2 |  exponentialStrength:10}}
 *   formats to: 1024
*/
@Pipe({
  name: 'exponentialStrength'
})
export class ExponentialStrengthPipe {
  transform(value:number, args:string[]) : any {
    return Math.pow(value, parseInt(args[0] || '1', 10));
  }
}

这里我们同样会用到annotation来声明一个管道。

代码

贴一段代码,这是官方的教程的,不过官方教程没写完,我加入了一个依赖注入的代码:

app.ts:

import {bootstrap, Component, FORM_DIRECTIVES, CORE_DIRECTIVES} from 'angular2/angular2';
import {HeroService, Hero} from "./heros";

@Component({
  selector: 'my-app',
  template: `
  <h1>My Heros</h1>
  <ul>
    <li *ng-for="#hero of heroes" (click)="onSelect(hero)" [ng-class]="getSelectedClass(hero)">{{hero.id}}:{{hero.name}}</li>
  </ul>
  <div *ng-if="selectedHero" >
    <h2>{{selectedHero.name}} details!</h2>
      <div>
        id: {{selectedHero.id}}
      <div>
      <label>name: </label>
      <input [(ng-model)]="selectedHero.name" placeholder="name" />
    </div>
  </div>
  `,
  styles: [`
    .selected {
      background: blue;
      color: white;
    }
  `],
  directives: [FORM_DIRECTIVES, CORE_DIRECTIVES]
})
class AppComponent {
  public title = 'Tour of Heroes';
  public heroes;

  public selectedHero: Hero;

  constructor(heroService: HeroService) {
    this.heroes = heroService.getHeroes();
  }

  public onSelect(hero: Hero) {
    this.selectedHero = hero;
  }

  public getSelectedClass(hero: Hero) {
    return { "selected" : hero == this.selectedHero }
  }
}

bootstrap(AppComponent, [HeroService]);

heros.ts:

import {Injectable} from 'angular2/angular2';

@Injectable()
export class HeroService {
  getHeroes() {

    var HEROES: Hero[] = [
      { "id": 11, "name": "Mr. Nice" },
      { "id": 12, "name": "Narco" },
      { "id": 13, "name": "Bombasto" },
      { "id": 14, "name": "Celeritas" },
      { "id": 15, "name": "Magneta" },
      { "id": 16, "name": "RubberMan" },
      { "id": 17, "name": "Dynama" },
      { "id": 18, "name": "Dr IQ" },
      { "id": 19, "name": "Magma" },
      { "id": 20, "name": "Tornado" }
    ];

    return HEROES;
  }
}

export class Hero {
  id: number;
  name: string;
}

参考:

版权声明:本文为博主原创文章,未经博主允许不得转载。

Angular2入坑指南

序对后端开发来说,前端是神秘的,眼花缭乱的技术,繁多的框架,出名的不出名的好几百种,看是“繁荣”,其实显得杂乱无章,但是我们在做开发的时候,技术选型还是主流的那么几个:浅析angular,react,...
  • xiangzhihong8
  • xiangzhihong8
  • 2016年12月25日 12:18
  • 11690

Angular2 VS Angular4 深度对比:特性、性能

本文将会对Angular2和Angular4进行深度对比,以便帮助大家更好的了解这两个版本。...
  • powertoolsteam
  • powertoolsteam
  • 2017年08月09日 11:56
  • 4785

实战Angular2+web api增删改查(三)

Angular2 开发 本示例使用了Angular2 RC4版本,另外由于使用了bootstrap,所以需要html中引入对应的css及js文件 入口 import { bootstrap } ...
  • huangyezi
  • huangyezi
  • 2016年07月11日 23:07
  • 11451

Angular2是可怕的

我们使用Angular 2作为我们的前端, 而我并没有参与这个决定,我是相对较晚才到这个项目工作。 这篇文章并不是对框架的全面评审,而是在使用了两个多星期后的一系列观察结果。 我不认为使用它了两个星期...
  • senmage
  • senmage
  • 2017年07月31日 17:55
  • 745

嗡汤圆的Angular2 单页应用一些优化总结

前言初学Angular2后很容易被它简洁清晰的思路,方便的开发环境和开发套件所吸引。但是真正考虑生产开发的时候,总是有些不那么美好的东西。所以,在这里总结一下一些最初级、最简单粗暴的优化步骤。启动时间...
  • tzdwsy
  • tzdwsy
  • 2017年03月21日 10:46
  • 3379

angular2学习记录-给后端程序员的经验分享

angular2学习记录-给后端程序员的经验分享标签(空格分隔): web1.前言前几天刚下定决心把毕业设计改造下,因为毕业设计算是我学习的基石,学习到的东西都尽可能的在这个平台上施展,锻炼自己.改造...
  • u012706811
  • u012706811
  • 2017年04月13日 21:33
  • 3592

揭秘angular2

  • 2017年11月19日 14:58
  • 102.79MB
  • 下载

Angular开发(二)-关于angular2的整体架构与大致介绍

说明:由于本人正在angular2或者说是angular4,只是把本人学习过程个人理解写出来,如果有写的不对的地方希望各位指出来,或者给我留言来纠正错误,相互学习,相互提高。本人QQ:33290423...
  • kuangshp128
  • kuangshp128
  • 2017年05月02日 20:49
  • 1244

几款常用的高质量web前端框架

Web前端框架就是为了节约开发成本和时间,一般开发一个项目都会用到前端框架(除非自己有前端开发团队),根据我经验找的几款web前端框架做出了分析。都是个人意见,仁者见仁智者见智。...
  • qianduankuangjia
  • qianduankuangjia
  • 2017年09月20日 17:06
  • 3216

七周七种前端框架三: Angular2 印象

巨大变化在 Angular1 中最重要的两个概念: directive 拓展DOM功能,封装DOM操作,并且是可复用的组件 controller 创建新的 $scope 作用域,封装和DOM无关的业务...
  • lihongxun945
  • lihongxun945
  • 2015年11月21日 15:14
  • 13720
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:七周七种前端框架三: Angular2 印象
举报原因:
原因补充:

(最多只允许输入30个字)