angular2自学笔记(二)---路由、服务等八大主要构造块

angular的思想:老是把数据访问工做委托给一个支持性服务类。

Angular 应用的:用 Angular 扩展语法编写 HTML 模板, 用组件类管理这些模板,用服务添加应用逻辑, 用模块打包发布组件与服务。

咱们经过引导根模块来启动该应用。 Angular 在浏览器中接管、展示应用的内容,并根据咱们提供的操做指令响应用户的交互。

angular2的八大主要构造块:
模块 (module)
组件 (component)
模板 (template)
元数据 (metadata)
数据绑定 (data binding)
指令 (directive)
服务 (service)
依赖注入 (dependency injection)

一。模块
Angular 应用是模块化的,而且 Angular 有本身的模块系统,它被称为 Angular 模块或 NgModules。
每一个 Angular 应用至少有一个模块(根模块),习惯上命名为AppModule。
根模块在一些小型应用中多是惟一的模块,大多数应用会有不少特性模块,每一个模块都是一个内聚的代码块专一于某个应用领域、工做流或紧密相关的功能。
Angular 模块(不管是根模块仍是特性模块)都是一个带有@NgModule装饰器的类。
装饰器是用来修饰 JavaScript 类的函数。 Angular 有不少装饰器,它们负责把元数据附加到类上,以了解那些类的设计意图以及它们应如何工做。


NgModule是一个装饰器函数,它接收一个用来描述模块属性的元数据对象。其中最重要的属性是:

官网解释:
imports - 本模块声明的组件模板须要的类所在的其它模块。
declarations - 声明本模块中拥有的视图类。 Angular 有三种视图类:组件、指令和管道。
exports - declarations 的子集,可用于其它模块的组件模板。
providers - 服务的建立者,并加入到全局服务列表中,可用于应用任何部分。
bootstrap - 指定应用的主视图(称为根组件),它是全部其它视图的宿主。只有根模块才能设置bootstrap属性。

理解:
imports:导入其余模块,就是要使用其余模块的功能,必需要导入。
declarations:声明,声明本模块包含的内容。可能有些同窗会遇到,定义了一个指令,在component中使用却老是没有生效的问题,首先咱们要检查的就是是否进行了声明。
exports:外部可见的内容。至关于.net中声明为public的那些类。
providers:服务提供者,主要用来定义服务。估计ng2框架会自动将注册的服务体检到依赖注入实例中,目前测试也是如此。
bootstrap:启动模块。只在根模块使用。在除了根模块之外的其余模块不能使用。


eg:javascript

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
@NgModule({
  imports:      [ BrowserModule ],
  providers:    [ Logger ],
  declarations: [ AppComponent ],
  exports:      [ AppComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

AppComponent的export语句只是用于演示如何导出的,它在这个例子中并非必须的。根模块不须要导出任何东西,由于其它组件不须要导入根模块。


Angular 模块 vs. JavaScript 模块
JavaScript 也有本身的模块系统,用来管理一组 JavaScript 对象。 它与 Angular 的模块系统彻底不一样且彻底无关。
JavaScript 中,每一个文件是一个模块,文件中定义的全部对象都从属于那个模块。 经过export关键字,模块能够把它的某些对象声明为公共的。 其它 JavaScript 模块可使用import 语句来访问这些公共对象。

引入:import {javascript模块名} from '文件相对路径';  
        使用装饰器以前须要从angular2的库中引入装饰器组件    import  {Component} from '@angular/core';
        从angular中导入angular模块: import {BrowserModule} from '@angular/platform-browser';

        两个系统比较容易混淆,共享相同的词汇 “imports” 和 “exports”。

定义:export class 模块名 { javascript代码块 }


二.组件
组件负责控制屏幕上的一小块区域,咱们称之为视图。

**组件在类中定义组件的应用逻辑,为视图提供支持。 组件经过一些由属性和方法组成的 API 与视图交互。html

export class HeroListComponent implements OnInit {
  heroes: Hero[];
  selectedHero: Hero;

  constructor(private service: HeroService) { }

  ngOnInit() {
    this.heroes = this.service.getHeroes();
  }

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

生命周期钩子:当用户在这个应用中漫游时,Angular会建立、更新和销毁组件。在组件生命周期的各个时间点上插入本身的操做,例如上面声明的ngOnInit()。生命钩子也须要提早引入import { OnInit } from '@angular/core';


 三.模板

     模板中能够任意使用自定义组件和原生HTML、模板语法(*ngFor、{{hero.name}}、(click)、[hero]);



四.元数据:元数据告诉 Angular 如何处理一个类

上边的组件HeroListComponent其实就是一个类,想要把类变为组件,须要把元数据添加到这个类,在TypeScript 中,咱们用装饰器 (decorator) 来附加元数据。java

@Component({
  moduleId: module.id,
  selector:    'hero-list',
  templateUrl: 'hero-list.component.html',
  providers:  [ HeroService ]
})
export class HeroListComponent implements OnInit {
  /* . . . */
}

@Component装饰器能接受一个配置对象, Angular 会基于这些信息建立和展现组件及其视图。

 @Component的配置项包括:
    moduleId: 为与模块相关的 URL(例如templateUrl)提供基地址。
    selector: CSS 选择器,它告诉 Angular 在父级 HTML 中查找<hero-list>标签,建立并插入该组件。 例如,若是应用的 HTML 包含<hero-list></hero-list>, Angular 就会把HeroListComponent的一个实例插入到这个标签中。
    templateUrl:组件 HTML 模板的模块相对地址,如前所示。
    providers:组件所需服务的依赖注入提供商数组,Angular:该组件的构造函数须要一个HeroService服务,这样组件就能够从服务中得到英雄数据。

@Component里面的元数据会告诉 Angular 从哪里获取你为组件指定的主要的构建块。模板、元数据和组件共同描绘出这个视图。
其它元数据装饰器用相似的方式来指导 Angular 的行为。 例如@Injectable、@Input和@Output等是一些最经常使用的装饰器。这种架构处理方式是:你向代码中添加元数据,以便 Angular 知道该怎么作。


五.数据绑定

    数据绑定的语法有四种形式。
    绑定到DOM:  [prototype]="value";    (even)="handle"    
    绑定到DOM:  {{vlue}}
    双向绑定:   [(ng-module)]="property";

    eg:
    {{hero.name}}插值表达式在<li>标签中显示组件的hero.name属性的值。
    [hero]属性绑定把父组件HeroListComponent的selectedHero的值传到子组件HeroDetailComponent的hero属性中。
    (click) 事件绑定在用户点击英雄的名字时调用组件的selectHero方法。
    <input [(ngModel)]="hero.name"> 双向数据绑定:数据属性值经过属性绑定从组件流到输入框。用户的修改经过事件绑定流回组件,把属性值设置为最新的值

    Angular 在每一个 JavaScript 事件循环中处理全部的数据绑定,它会从组件树的根部开始,递归处理所有子组件。


六.指令:Angular 模板是动态的。当 Angular 渲染它们时,它会根据指令提供的操做对 DOM 进行转换。

指令和模板的区别:
指令是一个带有“指令元数据”的类。在 TypeScript 中,要经过@Directive装饰器把元数据附加到类上。组件是一个带模板的指令;@Component装饰器实际上就是一个@Directive装饰器,只是扩展了一些面向模板的特性。

还有两种其它类型的指令:结构型指令和属性 (attribute) 型指令。
        1.结构型指令:经过在 DOM 中添加、移除和替换元素来修改布局。
            <li *ngFor="let hero of heroes"></li>
            <hero-detail *ngIf="selectedHero"></hero-detail>

        2.属性型指令:修改一个现有元素的外观或行为。 在模板中,它们看起来就像是标准的 HTML 属性。
            ngModel指令就是属性型指令的一个例子,它实现了双向数据绑定。 ngModel修改现有元素(通常是<input>)的行为:设置其显示属性值,并响应 change 事件。
            <input [(ngModel)]="hero.name">

        3.自定义指令:如上面的HeroListComponent就是一个自定义指令


七.服务:

    一个把记录到console.log的服务类示例:bootstrap

export class Logger {
          log(msg: any)   { console.log(msg); }
          error(msg: any) { console.error(msg); }
          warn(msg: any)  { console.warn(msg); }
        }

经过向后台传递数据并经过一个已接收的promise返回数据:数组

export class HeroService {
          private heroes: Hero[] = [];

          constructor(
            private backend: BackendService,
            private logger: Logger) { }

          getHeroes() {
            this.backend.getAll(Hero).then( (heroes: Hero[]) => {
              this.logger.log(`Fetched ${heroes.length} heroes.`);
              this.heroes.push(...heroes); // fill cache
            });
            return this.heroes;
          }
        }

服务的getHeroes()和addHero()方法返回一个英雄数据的可观察对象Observable这些数据是由AngularHttp从服务器上获取的。咱们能够把可观察对象Observable看作一个由某些“源”发布的事件流。 经过订阅到可观察对象Observable,咱们监听这个流中的事件。 在这些订阅中,咱们指定了当 Web 请求生成了一个成功事件(有效载荷是英雄数据) 或失败事件(有效载荷是错误对象)时该如何采起行动。

    组件自己不从服务器得到数据、不进行验证输入,也不直接往控制台写日志。 它们把这些任务委托给服务。
    组件的任务就是提供用户体验。它介于视图(由模板渲染)和应用逻辑(一般包括模型的某些概念)之间。设计良好的组件为数据绑定提供属性和方法,把其它杂事都委托给服务。把应用逻辑拆分到服务,并经过依赖注入来在组件中使用这些服务。

八.依赖注入:
    “依赖注入”是提供类的新实例的一种方式,还负责处理好类所需的所有依赖。大多数依赖都是服务。Angular使用依赖注入来提供新组件以及组件所需的服务。
    Angular 经过查看构造函数的参数类型得知组件须要哪些服务。 例如,HeroListComponent组件的构造函数须要一个HeroService服务:
        constructor(private service: HeroService) { }
    当 Angular 建立组件时,会首先为组件所需的服务请求一个注入器 (injector)。

    依赖注入的流程:
        注入器维护了一个服务实例的容器,存放着之前建立的实例。若是所请求的服务实例不在容器中,注入器就会建立一个服务实例,而且添加到容器中,而后把这个服务返回给Angular。当全部请求的服务都被解析完并返回时,Angular会以这些服务为参数去调用组件的构造函数。

    在要求注入HeroService以前,在注入器中注册HeroService的提供商 Provider。 提供商用于建立并返回一个服务,一般是服务类自己。
咱们能够在模块或组件中注册提供商。一般会把提供商添加到根模块上,以便在任何地方使用服务的同一个实例。promise

providers: [
          BackendService,
          HeroService,
          Logger
        ],

也能够在@Component元数据中的providers属性中把它注册在组件层,表示该组件的每个新实例都会有一个服务的新实例。浏览器

@Component({
          moduleId: module.id,
          selector:    'hero-list',
          templateUrl: 'hero-list.component.html',
          providers:  [ HeroService ]
        })

须要记住的关于依赖注入的要点是:
        依赖注入渗透在整个 Angular 框架中,被处处使用。
        注入器 (injector) 是本机制的核心。
        注入器负责维护一个容器,用于存放它建立过的服务实例。
        注入器能使用提供商建立一个新的服务实例。
        提供商是一个用于建立服务的配方。
        把提供商注册到注入器。服务器

相关文章
相关标签/搜索