Angular2 ARCHITECTURE OVERVIEW学习笔记

官网地址:https://angular.io/docs/ts/latest/guide/architecture.html

结构图

Angular结构图
Angular结构图

结构图囊括了构成一个Angular2应用的八块主要内容

  1. Module
  2. Component
  3. Template
  4. Metadata
  5. Data Binding
  6. Directive
  7. Service
  8. Dependency Injection

Module

Module:模块

Angular应用是模块化的,通常我们的应用是由许多个模块集合而成的。

一个典型的模块,包含着一串只专注于实现一个目的的代码,它会导出这串代码中有价值的东西,最典型的是一个类。

我们之前(在demo2中)见识过了模块导出一个组件类,由此可知组件类也是由模块导出的东西之一。

大部分应用都含有一个<code>AppComponent</code>,通常,我们可以在一个名为<code>app.component.ts</code>的文件中找到它。文件中会有一句这样的声明:

export class AppComponent { }

这个<code>export</code>声明告诉TypeScript,这是一个模块,它拥有一个<code>AppComponent</code>类,这个类是公开的,并且可供应用中其他模块进行调用。

当我们需要对<code>AppComponent</code>进行引用时,像这样将它导入:

import { AppComponent } from './app.component';

<br />

Library Modules

一些模块是另外一个模块的库。

Angular本身集结了许多模块库,他们被放在npm包中。他们的名字以<code>@angular</code>打头。

<code>@angular/core</code>是一种常见的初级模块库,我们所需要的大部分东西都可以从中取得。

还有一些常见的模块库,比如
<code>@angular/common</code>,<code>@angular/router</code>,<code>@angular/http</code>等等。

我们导入库的方法是类似的,比如我们导入Angular<code>Component
</code>函数

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

对比一下之前导入我们自己创建的<code>AppComponent</code>

import { AppComponent } from './app.component';

可以发现,路径名是不同的。

Key
  1. Angular应用是一系列模块构成的。
  2. 模块总会导出一些东西,比如类、函数或者值,然后这些东西被其他的模块所引用。
  3. 我们偏向于将应用写成模块的集合,一个模块导出一样东西(专注于一个目的)。
    <br />

The Component

一个组件控制一个视图。

例如,<code>HeroListComponent</code>,拥有一个<code>heroes</code>属性,这个属性从一个服务中返回一个heroes的数组。它还拥有一个<code>selectHero()</code>方法,这个方法在用户从列表中点击一个hero时,设置一个<code>selectedHero</code>属性。

export class HeroListComponent implements OnInit {
  constructor(private service: HeroService) { }
  heroes: Hero[];
  selectedHero: Hero;
  ngOnInit() {
    this.heroes = this.service.getHeroes();
  }
  selectHero(hero: Hero) { this.selectedHero = hero; }
}

Angular在用户使用应用的时候,创建、更新、销毁组件,开发者可以在这个生命周期的任一时刻采取任何行动。
<br />

The Template

我们在组件中定义template,一个template是HTML的一部分,它告诉Angular如何渲染组件。

一个template大部分与HTML很相似,但也有不同的地方。这是<code>HeroList</code>组件中的template。

<h2>Hero List</h2>
<p><i>Pick a hero from the list</i></p>
<div *ngFor="let hero of heroes" (click)="selectHero(hero)">
  {{hero.name}}
</div>
<hero-detail *ngIf="selectedHero" [hero]="selectedHero"></hero-detail>

<code><hero-detail></code>标签代表着<code>HeroDetailComponent</code>.

<code>HeroDetailComponent</code>可以说是<code>HeroListComponent</code>的孩子。Root Template中包含Child Component和Child Template,Child Template中又包含GrandChild Component和GrandChild Template.我们可以这样将组件混合起来,利用原生的HTML元素,在同一个页面中进行展示。

我们将组建复杂的组件树,来创建我们功能丰富的应用。
<br />

Angular Metadata

Metadata告诉Angular如何处理一个类。

当我们回过头来看<code>HeroListComponent</code>时,它像一个类,直到我们告诉Angular这是一个组件。我们使用给这个类附上metadata的方式来告诉Angular.

一个简单有效的附带metadata的方法是使用decorator。

@Component({
  selector:    'hero-list',
  templateUrl: 'app/hero-list.component.html',
  directives:  [HeroDetailComponent],
  providers:   [HeroService]
})
export class HeroesComponent { ... }

这里我们使用了<code>@Component</code>decorator.

一个decorator是一个函数。Decorators通常有一个构造参数。<code>@Component</code>decorator包含了一个对象,这个对象携带有Angular需要创建和展示的组件及其视图的全部信息。

接下来我们看看<code>@Component</code>中可能包含的选项。

  1. selector
    css选择器告诉Angular在HTML找到<code><hero-list></code>标签,在标签里创建然后插入这个<code>HeroListComponent</code>的视图。
  2. templateUrl
    组件template所在地址,template是组件要展示出来的视图。
  3. directives
    template所需的Components或者Directives的一个数组。刚才我们提到,template希望Angular在<code><hero-detail></code>标签出现的地方插入<code>HeroDetailComponent</code>,而只有当<code>HeroDetailComponent</code>在<code>directives</code>被提到之后,Angular才会按照我们所期待的那样去做。
  4. providers
    这是一个数组,数组中对组件所需的服务提供了依赖注入。可以使用这个方法来告诉Angular,我们的组件需要<code>HeroService</code>,这样它可以从这个服务中获得英雄列表来展示。

总结:The @Component function takes the configuration object and turns it into metadata that it attaches to the component class definition. Angular discovers this metadata at runtime and thus knows how to do "the right thing".
The template, metadata, and component together describe the view.
<br />

Data Binding

data binding
data binding

没有框架的帮助时,我们需要将数据push进html,然后获取用户的响应动作,以此来更新数据。这样手动实现push/pull逻辑是很乏味的。

Angular支持data binding,一种使得template和组件其他部分能够相互协作的机制。

data binding语法有四种。这里我们展示了三种。

<div>{{hero.name}}</div>
<hero-detail [hero]="selectedHero"></hero-detail>
<div (click)="selectHero(hero)"></div>

interpolation在<code><div></code>标签中展示了组件的<code>hero.name</code>属性。
property binding 通过<code>[hero]</code>将父组件<code>HeroListComponent</code>的<code>selectedHero</code>,传给了孩子组件<code>HeroDetailComponent</code>的属性<code>hero</code>.
event binding <code>(click)</code>是一个事件绑定,它将在用户点击hero's name时调用<code>selectHero</code>方法。
Two-way data binding通过使用<code>ngModel</code>指令可以实现属性和事件的结合绑定。

<input [(ngModel)]="hero.name">

用户的输入改变同样会回传给组件,造成组件中属性的改变。


template与component binding
template与component binding

parent与child binding
parent与child binding

data binding在template与它的组件的沟通中起到了重大的作用。
<br />

The Directive

templates是动态变化的,当Angular对它进行渲染时,它根据directive给的指示对DOM做出改变。

一个 directive是一个有directive metadata的类。在Typescript中我们使用<code>@Directive</code>decorator来将metadata与类连接。

组件也是directive的一种。<code>@Component</code>decorator是含有template的一种<code>@Directive</code>decorator.

Directives中有两种,我们称之为"structural" 和 "attribute" 的directives.他们通常出现在HTML标签中,就像attributes一样。

Structural directives通过对DOM进行增添、移动、替代操作来展示视图。

<div *ngFor="let hero of heroes"></div>
<hero-detail *ngIf="selectedHero"></hero-detail>

<code>*ngFor</code>告诉Angular用<div>对<code>heroes</code>列表中的每一个hero进行展示。
<code>*ngIf</code>只有当选中的hero存在时,包含<code>HeroDetail</code>.

Attribute directives对存在的元素进行外观或者行为的操作。在template中,它们看起来就像常规的HTML attributes.

<input [(ngModel)]="hero.name">

<code>ngModel</code>改变了已经存在的元素<code><input></code>的行为,设置了它展示出来的属性值,使它对输入改变这个事件作出响应。
<br />

The Service

Service包含着大量我们所需要的函数、值、属性。几乎所有东西都可以成为service。service是一个拥有单一目的的类。举例:
logging service
data service
message bus
tax calculator
application configuration

Angular自身没有关于service的定义,也就是说,并没有一个service的基类。

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

  private heroes: Hero[] = [];

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

<code>HeroService</code>依赖于<code>LoggerService</code>和<code> BackendService</code>.它fetch一个hero,并返回它。

组件是service的主要服务对象。它们依赖service去掌控细枝末节。它们将诸如从服务器获取数据、验证用户输入这样的琐事交给service。

Angular使得我们将应用逻辑写入service变得简单,并且通过依赖注入使得service对组件是可用的。
<br />

Dependency Injection

"Dependency Injection"是一种提供类的新实例的方式,它包含了类所需的所有依赖。大部分依赖都是service。Angular给component提供它们所需的service.

constructor(private service: HeroService) { }

当Angular创建一个新的组件时,它首先会向Injector要求组件所需的service。

一个Injector掌控含有预先创建的service实例的容器。如果所需service不在这个容器中,injector会在对Angular响应之前创建一个,并把它加入到容器中。当Angular得到了所有所需的service,将这些service作为参数传入到组件构造器中。

HeroService injection
HeroService injection

当没有<code>HeroService</code>时,如何创建一个service?

简要地说,我们必须有一个事先注册好的<code>HeroService</code>的provider,provider可以创建或者返回service。

我们可以再应用组件树的任何一层注册provider。我们通常在根部完成此事,在我们bootstrap我们的应用时。这样这个service的实例就可以在任何位置被调用了。

bootstrap(AppComponent, [BackendService, HeroService, Logger]);

bootstrap是启动和配置根应用组件的方法。

key
  1. injector掌控一个含有它创建的service实例的容器。
    injector可以利用provider创建一个它没有的service实例。
  2. provider对于创建service来说就像食谱。
  3. 我们通过injector注册provider.
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容

  • Angular 2是一个帮助我们使用HTML和JavaScript构建客户端应用的框架。这个框架包含几个互相协作的...
    JasonQiao阅读 6,988评论 1 48
  • Angular 2架构总览 - 简书http://www.jianshu.com/p/aeb11061b82c A...
    葡萄喃喃呓语阅读 1,432评论 2 13
  • 学习资料来自 Angular.cn 与 Angular.io。 模板语法 在线例子 在 Angular 中,组件扮...
    小镭Ra阅读 3,613评论 0 3
  • 版本:Angular 5.0.0-alpha AngularDart(本文档中我们通常简称 Angular ) 是...
    soojade阅读 800评论 0 4
  • 《倾城之恋》里,范柳原对白流苏说:有人善于说话,有人善于笑,有人善于管家,你是善于低头的。 此间的阿碧姑娘,则是善...
    浅海不浅阅读 634评论 2 3