zoukankan      html  css  js  c++  java
  • 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:

    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 与视图交互。

    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) 来附加元数据。

    @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的服务类示例:

    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。 提供商用于创建并返回一个服务,通常是服务类本身。
    我们可以在模块或组件中注册提供商。通常会把提供商添加到根模块上,以便在任何地方使用服务的同一个实例。

    providers: [
              BackendService,
              HeroService,
              Logger
            ],

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

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

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

  • 相关阅读:
    2019-2020-1 20175201 20175215 20175229实验五 通讯协议设计
    2019-2020-1 20175201 20175215 20175229实验四 外设驱动程序设计
    2019-2020-1 实验三-并发程序 20175215
    20175201 20175215 20175229 实验二 固件程序设计
    冲刺博客汇总
    2018-2019-2 20175215 实验五《网络编程与安全》实验报告
    Int和Integer(课上测试)
    MySort(选做)
    2019-2020-2 20175234 赵诗玥 《网络对抗技术》 Exp1 PC平台逆向破解
    2019-2020-2 20175234 赵诗玥《网络对抗技术》 Exp0 Kali安装
  • 原文地址:https://www.cnblogs.com/jasonwang2y60/p/6280375.html
Copyright © 2011-2022 走看看