本文为原创,转载请注明出处: cnzt       文章:cnzt-p

http://www.cnblogs.com/zt-blog/p/7762590.html

前提:

angular-cli (前提:nodejs npm)

typescript

搭建骨架项目步骤:

ng new my-ng2-app 创建一个新的名字为my-ng2-app的骨架项目;

cd my-app 进入到项目目录下

ng serve --open 启动开发服务器并监听文件变化,参数open打开浏览器并自动访问http://localhost:4200/

页面及编译后的文件如下:

搭建英雄教程:

  参考: https://angular.cn/tutorial/

指令(Directive):

  Angular的指令有三种:结构性指令(如 ngSwitch、ngIf、ngFor等)、属性型指令(ngClass、ngStyle、ngModel等)、自定义指令(如 组件component)

组件(Component):

  首先,组件也是指令,是实现了模板特性的指令。

  定义一个组件: (此处的OnInit为生命周期钩子函数,常在初始化组件数据时用到)

    1. 引入组件方法   (import { Component, OnInit } from '@angular/core';)

    2. @Component修饰器 (

      @Component({})

      export class AppComponent implements OnInit { .. }

    )

    3. 如果一个组件有输入参数,那么他还需引入@Input,如下:

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

      import { Hero } from './hero';

      

      @Component({
        selector: 'hero-detail',
        template: ``,
      })
      export class HeroDetailComponent{
        @Input() hero: Hero;  // 通过 <hero-detail hero='selectedHero'> 传值的
      }

模块 Module:

  模块分为跟模块和子模块。

  模块包含了完成特定功能的一组组件。

  定义一个模块:

    1. 引入NgModule (import { NgModule }      from '@angular/core';)

    2. 通过@NgModule定义模块的元数据并到处模块 (

      @NgModule({
        imports: [
          BrowserModule,
          FormsModule  // 绑定 [(ngModel)]时需要此模块
        ],
        declarations: [ AppComponent, HeroDetailComponent ],  // 生命此模块包含的视图:组件,指令,管道
        bootstrap: [ AppComponent ]
      })
      export class AppModule { }

    )

    3. 一个新组的建件,需要import到相应的Module模块中,并声明到declarations:[]数组中。

服务:

  Angualr的服务本质上师一个类,专注于做某件事情的类。实际应用中我们通常用服务来获取后台数据、管理日志、校验数据等等。再通过依赖注入在组件中使用这些服务,而组件就应该保持精简,琐事交给服务处理。

  服务可以注册(providers:[XX,XX,...])在根模块中,也可以注册在组件的元数据中。注册在根模块中表示所有地方使用同一个服务的实例,注册在组件中表示每一个新的组件实例都会有一个新的服务实例。

  服务要素:

  1. 定义一个服务

    1.1 引入Injectable (import { Injectable } from '@angular/core';)

    1.2 @Injectable修饰器 (

      @Injectable()
      export class HeroService{}

    )

    1.3 Promise处理异步

  2. 在组件等中调用服务(依赖注入)

    2.1 引入所需服务 (import { HeroService } from './hero.service';)

    2.2 在服务提供商完成注册 (providers: [HeroService ])

    2.3 组件的构造函数中通过传入一个私有变量完成依赖注入 (constructor(private heroService: HeroService){ 。。。 })

    2.4 调用 this.heroService.XXX  (this.heroService.getHeroes().then(。。。))

路由:

  1. 基地址是必须的:  <base href>组件,位于<head>区域内顶部。

  2. 模块文件中引入 import { RouterModule } from '@angular/router';

      import元数据中定义:

    RouterModule.forRoot([ //应用根部
       {
      path: 'heroes',
      component: HeroesComponent
       }
    ])

  3. 路由组件中就可以定义路由和路由模板了:

    <a routerLink='/heroes'>Heroes</a>  // 路由路径
    <router-outlet></router-outlet>  // 路由模板/容器

  4. 关于重定向:

    {
      path: '',    // 给初始路径重定向
      redirectTo: '/dashboard',
      pathMatch: 'full'
    }

  5.带参数的路由:

    5.1 路由器配置:

    {
      path: 'detail/:id',
      component: HeroDetailComponent
    }

    5.2 组件中接收参数:

    引入ActivatedRoute 和 ParamMap: ( import { ActivatedRoute, ParamMap } from '@angular/router'; );

    将引入的服务依赖注入到constructor里;

    引入switchMap:  import 'rxjs/add/operator/switchMap';

    组件中接收参数的具体操作:

      ngOnInit(): void{
        this.route.paramMap
          .switchMap((params: ParamMap) => this.heroService.getHero(+params.get('id')))
          .subscribe(hero => this.hero=hero;)
      }

    导航方式1:模板中传递参数:   <a *ngFor="let hero of heroes" [routerLink]="['/detail', hero.id]" class="col-1-4">

    导航方式2:组件中调用:  this.router.navigate(['/detail', this.selectedHero.id]);

路由模块:

将路由部分重新定义成一个新的模块。典型路由模块需要注意的有:

  • 将路由抽出到一个变量中。如果你将来要导出这个模块,这种 "路由模块" 的模式也会更加明确。

  • 添加RouterModule.forRoot(routes)imports

  • RouterModule添加到路由模块的exports中,以便关联模块(比如AppModule)中的组件可以访问路由模块中的声明,比如RouterLink 和 RouterOutlet

  • declarations!声明是关联模块的任务。

  • 如果有守卫服务,把它们添加到本模块的providers中。   

HTTP:

  一般我们用http服务获取server数据,但在开发前期,也可以利用InMemoryWebApi来实现本地模拟http测试接口。

  本地模拟测试:

  1. 引入相应模块

  import { HttpModule } from '@angular/http';

  import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
  import { InMemoryDataService } from './in-memory-data.service';

  2. 模块导入跟模块中

  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    InMemoryWebApiModule.forRoot(InMemoryDataService),
    AppRoutingModule
  ],

  3. 定义一个产生本地(数据库)数据的文件 : in-memory-data.service.ts :

  import { InMemoryDbService } from 'angular-in-memory-web-api';
  export class InMemoryDataService implements InMemoryDbService {
    createDb() {
      const heroes = [
        { id: 0, name: 'Zero' },
        { id: 11, name: 'Mr. Nice' },
        { id: 12, name: 'Narco' },    

        ...
      ];
      return {heroes};
    }
  }

  4. 相应的service中应用http服务:

  import { Headers, Http } from '@angular/http';

  import 'rxjs/add/operator/toPromise'; //将obervable可观察对象转换成Promise对象的操作符

  @Injectable()
  export class HeroService{
    private heroesUrl = 'api/heroes';//这里的heroes对应本地mock数据返回的那个字段

    constructor(private http: Http){}

    getHeroes(): Promise<Hero[]> { //stub桩方法

    //以下为模拟web-api方式实现
    //InMemoryWebApiModule将Http客户端默认的后端服务(这是一个辅助服务,负责与远程服务器对话) 替换成了内存 Web API服务:
    return this.http.get(this.heroesUrl) //http.get返回一个 RxJS 的Observable对象
      .toPromise() //利用toPromise操作符把Observable直接转换成Promise对象
      .then(response => response.json().data as Hero[]) //调用 HTTP 的Reponse对象的json方法
      .catch(this.handleError);
    }

    private handleError(error: any): Promise<any>{
      console.error('An error occured', error); // for demo purposes only
      return Promise.reject(error.message || error);
    }
  }

  5. 以上就是基本的本地模拟http的实现步骤。

可观察对象: Observable

  一个可观察对象是一个事件流,可以用数组型操作符处理它。

  Angular内核提供了对可观察对象的基本支持。我们也可以引入RxJS库进行扩展,例如上面见到的http.get().toPromise()...就是利用toPromise操作符将http.get()返回的可观察对象转换成了Promise承诺。

  *****那么,既然我们可以用承诺Promise,为啥开发中还会需要可观察对象的方式呢?因为请求并非总是“一次性”的,我们开始一个请求并取消它,在server响应第一个求情之前再开始另一个不同的请求。像这样的 请求--取消--新请求 序列用 Promise是难以实现的,但是可观察对象却很容易实现。*****

  ------------------------------------------------------本小节待续------------------------------------------

测试:

  1. 单元测试UT: karma (karma.conf.js)

  2. 端到端测试e2e: protractor (protractor.conf.js)

JiT和AoT:

Angular 的即时编译(JiT)在浏览器中启动并编译所有的组件和模块,动态运行应用程序。 它很适合在开发过程中使用。但是在产品发布时,推荐采用预编译 (ahead-of-time) 模式。

参考: https://www.angular.cn/guide/quickstart

Angular2.X 笔记的更多相关文章

  1. angular2自学笔记---官网项目(一)

    1.单向数据绑定的'插值表达式' angular中最典型的数据显示方式:把HTML模板(template)的控件绑定到angular组件的属性(component相当于一个构造函数,下面例子中的这个构 ...

  2. angular2 学习笔记 ( rxjs 流 )

    RxJS 博大精深,看了好几篇文章都没有明白. 范围牵扯到了函数响应式开发去了... 我对函数式一知半解, 响应式更是第一次听到... 唉...不过日子还是得过...混着过先呗 我目前所理解的很浅,  ...

  3. angular2 学习笔记 ( ngModule 模块 )

    2016-08-25, 当前版本是 RC 5. 参考 : https://angular.cn/docs/ts/latest/guide/ngmodule.html 提醒 : 这系列笔记的 " ...

  4. Angular2学习笔记(1)

    Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...

  5. Angular2开发笔记

    Problem 使用依赖注入应该注意些什么 服务一般用来做什么 指令一般用来做什么 angular2如何提取公共组件 angular2为什么不需要提公共组件 父组件与子组件之间如何通讯 什么时候应该使 ...

  6. Angular2学习笔记——路由器模型(Router)

    Angular2以组件化的视角来看待web应用,使用Angular2开发的web应用,就是一棵组件树.组件大致分为两类:一类是如list.table这种通放之四海而皆准的通用组件,一类是专为业务开发的 ...

  7. Angular2学习笔记——Observable

    Reactive Extensions for Javascript 诞生于几年前,随着angular2正式版的发布,它将会被更多开发者所认知.RxJs提供的核心是Observable对象,它是一个使 ...

  8. Angular2学习笔记——在子组件中拿到路由参数

    工作中碰到的问题,特此记录一下. Angular2中允许我们以`path\:id\childPath`的形式来定义路由,比如: export const appRoutes: RouterConfig ...

  9. Angular2学习笔记——NgModule

    在Angular2中一个Module指的是使用@NgModule修饰的class.@NgModule利用一个元数据对象来告诉Angular如何去编译和运行代码.一个模块内部可以包含组件.指令.管道,并 ...

  10. angular2 学习笔记 ( Form 表单 )

    refer : https://angular.cn/docs/ts/latest/guide/forms.html https://angular.cn/docs/ts/latest/cookboo ...

随机推荐

  1. GIMP永久保存选择的办法

    选择选区,然后把选区放到channel里面去 这是一张已经选择好的选区的图片 然后选择select下的Save to Channel, 需要这部分选区的话,只需要点击这个按钮就可以了

  2. 《嵌入式linux应用程序开发标准教程》笔记——8.进程间通信

    , 8.1 概述 linux里使用较多的进程间通信方式: 管道,pipe和fifo,管道pipe没有实体文件,只能用于具有亲缘关系的进程间通信:有名管道 named pipe,也叫fifo,还允许无亲 ...

  3. 《零基础入门学习Python》【第一版】视频课后答案第004讲

    1.while语句中,当条件为真时,它会一直循环下去,比如下面的例子,不过可以用Ctral + C来强制结束 while 'C': print("i love you") 2.观察 ...

  4. python 中变量和对象

    1. 在 python 中,类型属于对象,变量是没有类型的:a=[1,2,3] a="Runoob"以上代码中,[1,2,3] 是 List 类型,"Runoob&quo ...

  5. [转]automaticallyAdjustsScrollViewInsets(个人认为iOS7中略坑爹的属性)

    @当我们在一个UIViewController中同时创建2个tableView的时候,如果把它们的frame中的Y坐标设置为一样,你可能会发现它们的位置并没有达到你想要的结果.比如第一tableVie ...

  6. BFS:UVa201-Squares

    Squares A children's board game consists of a square array of dots that contains lines connecting so ...

  7. django的rest framework框架——认证、权限、节流控制

    一.登录认证示例 模拟用户登录,获取token,当用户访问订单或用户中心时,判断用户携带正确的token,则允许查看订单和用户信息,否则抛出异常: from django.conf.urls impo ...

  8. Linux下二进制文件安装MySQL

    MySQL 下载地址:https://dev.mysql.com/downloads/mysql/ 并按如下方式选择来下载安装包. 1. 设置配置文件/etc/my.cnmore /etc/my.cn ...

  9. javascript异常cannot read property xx of null 的错误

    一般报这种异常或者错误,是因为试图从null中再读一个属性导致的. 比如:var myAttr=myObj.data.Name; 假如这个时候myObj.data是null,那么再试图读取data的N ...

  10. 九度oj 题目1472:求两个多项式的和

    题目描述: 输入两个多项式,计算它们的和. 每个多项式有若干对整数表示,每组整数中,第一个整数表示系数(非0),第二个整数表示该项的次数. 如由3 3 5 -2 1 4 0表示3x^5 - 2 * x ...