zoukankan      html  css  js  c++  java
  • Angular2.X 笔记

    本文为原创,转载请注明出处: 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

  • 相关阅读:
    RocketMQ性能压测分析(转载)
    利用Fiddler或Charles进行mock数据
    Linux中buffer/cache,swap,虚拟内存和page ++
    AVA 8 :从永久区(PermGen)到元空间(Metaspace)
    jstat 监控调整GC很好用
    Jmeter常用函数
    关于Oracle新建表空间,添加用户及新建表数据
    关于Oracle增加表空间大小方法
    关于手动删除Oracle数据数据,导致Oracle无法连接处理过程
    解决jquery easyui combotree(下拉树)点击文字无法展开下级菜单的解决方法
  • 原文地址:https://www.cnblogs.com/zt-blog/p/7762590.html
Copyright © 2011-2022 走看看