You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<h2>Hero List</h2><p><i>Pick a hero from the list</i></p><div*ngFor="#hero of heroes" (click)="selectHero(hero)">
{{hero.name}}
</div><hero-detail*ngIf="selectedHero" [hero]="selectedHero"></hero-detail>
Angular 2 是一个帮助我们使用 HTML 和 JavaScript 构建客户端应用的框架。
该框架由几个相互协同的库组成,其中一些是核心的,另一些是可选的。
我们通过 Angular 化的标签合成 HTML 模板,编写组件类来管理这些模板,通过 service 为应用添加逻辑,使用 Angular 的启动器来操控最顶层的根组件。
Angular 在浏览器中管理并展示应用的内容,并且根据提供的指令来响应用户的交互。
当然不仅如此,当我们深入挖掘后会学习到更多细节。首先,让我们有个整体上的了解。
上面的架构图展示了一个了 Angular 2 应用的八个主要构建部分:
模块
Angular 应用是模块化的。
一个应用一般是由多个模块组装而成。
一个典型的模块遵循单一职责的原则。模块会向外暴露(exports)一些值,比如一个类。
可能我们所见的第一个模块是一个暴露一个组件类的模块。组件是 Angular 的基础块,我们将会在下一节讨论。现在暂时只要知道组件类是从模块中暴露出来的一个物体。
Angular 应用中有一个
AppComponent
。按照惯例,我们会从一个名为app.component.ts
的文件中找到它。在这个文件中可以看到如下的export
语句:export
语句告诉 TypeScript 这是一个模块,该模块暴露了AppComponent
类因此应用中的其他模块就可以访问这个组件。当需要引用
AppComponent
组件,使用import
:import
语句告诉系统它可以从一个名为app.component
模块获取AppComponent
组件。模块名通常和它省略后缀名的文件名一样。库模块
有一些模块是其它模块的库称之为库模块。
Angular 提供了被称之为『桶』(barrels)的一系列库模块(Multiple modules (files) can be logically grouped into so-called "barrels". )。实际上每个 Angular 库是将依赖私有模块的一些逻辑暴露出来。
angular2/core
是 Angular 的基本库模块。其它也有一些重要的 Angular 库模块例如angular2/common
、angular2/router
和angular2/http
。使用同样的方式导入所需的 Angular 库模块。例如,从
angular2/core
库模块导入Component
函数较之上文导入的
AppComponent
:第一种情况,从 Angular 库模块导入,不需要路径前缀而仅仅引用模块名。
当导入一个自己的文件,使用路径前缀。在例子中,我们指定了一个相对路径(./)。
关键点:
多数情况下,我们的第一个模块暴露的是一个组件。
组件
一个组件控制屏幕上的真实资源,我们称之为视图(View)。官方 Demo 中的导航链接、英雄列表、英雄编辑器等等,这些所有的视图都被组件所控制。
在类中定义组件逻辑来呈现视图。类通过属性和方法的 API 和视图进行交互。
比如,
HeroListComponent
组件可能有一个heroes
属性,该属性从一个服务(service)返回一个英雄数组。这个组件同时可能会有一个selectHero()
方法来设置selectedHero
属性,表示当用户从列表中选中一个英雄。这个类像下面这样:Angular 通过用户在应用中的行为来创建、更新和销毁组件。开发者通过可选的生命周期钩子在整个生命周期中完成一些工作。
模板
我们通过相关的模板来定义组件的视图。模板是 HTML 格式,用来告诉 Angular 如何去渲染组件。
多数情况下,模板看上去像一个标准的 HTML,但也有略微的不同。下面是
HeroList
组件的模板。我们认识
<h2>
和<div>
。但是有些标签我们并没有见过。*ngFor
,{{hero.name}}
,(click)
,[hero]
和<hero-detail>
都是个什么鬼?这里有 Angular 模板语法的例子。我们会很快熟悉这种语法,甚至会喜欢上它。
注意最后一行。
<hero-detail>
标签是一个自定义元素,代表HeroDetailComponent
组件。通过同样的布局,我们可以连续混入多个自定义组件。借助这样的方式,将会组合出一个复杂的组件树来构建具有丰富特性的应用。Angular 元数据
元数据告诉 Angular 如何处理类(class)。
我们回过来看
HeroListComponent
,看到的仅仅只是个类。当我们告诉 Angular 之前,这并不是一个组件。我们通过类绑定的元数据(metadata)来告诉 Angular
HeroListComponent
是一个组件。TypeScript 中最简单地绑定元数据方式通过修饰器(decorator )。
这里我们可以看到
@Component
修饰器,下面也随即出现组件类的定义。一个修饰器是一个函数,通常需要一个配置参数。
@Component
修饰器获取一个配置对象,该配置对象为 Angular 提供创建并展示组件和视图的信息。正如我们看到的一部分
@Component
的配置选项:selector
- 一个 CSS 选择器,告诉 Angular 当在父级 HTML 中找到<hero-list>
标签时,创建并插入这个组件实例。templateUrl
- 我们将要展示的组件模板的文件地址。directives
- 模板要求的组件或者指令的集合。我们可以看到模板的最后一行期盼 Angular 插入<hero-detail>
标签标识的HeroDetailComponent
组件。我们只有在这个directives
数组中标记HeroDetailComponent
,Angular 才会做插入工作,否则将无法识别这个标签。providers
- 组件要求的为服务提供依赖注入的集合。这里告诉 Angular,组件的构造器需要一个HeroService
获取英雄列表来展示。@Component
函数将获取来的配置对象转换为组件类定义相关的元数据。Angular 在运行期发现元数据然后创建组件。模板、元数据和组件共同描述一个视图。
用类似的方式,运用其它元数据修饰器来引导 Angular 的行为。当我们对 Angular 更加熟悉后,需要精通
@Injectable
,@Input
,@Output
,@RouterConfig
这几个比较流行的修饰器。必须为我们的代码添加元数据让 Angular 知道该去做什么。
数据绑定
在没有框架的前提下,如果需要负责将数据推送给 HTML 显示并且将用户的响应转换为相关的动作(action)和数据更新,像这样纯手工完成推送和更新的逻辑,有 jQuery 经验的开发者会觉得这非常乏味、容易出错而且难以阅读。
Angular 支持数据绑定(data binding),这是一种用来协调模板和组件交互的机制。我们给 HTML 模板添加绑定标记来告诉 Angular 如何将模板和组件联系起来。
这里有四种形式的数据绑定语法。每种形式都有一个方向,记入图中箭头所标记的:到 DOM 中去、从 DOM 中来或者双向流动。
在我们的例子中,我们可以看到三种形式的数据绑定:
hero.name
属性值被插入到<div>
标签中。[hero]
属性绑定,将父级组件HeroListComponent
的selectedHero
值传递给子组件HeroDetailComponent
的hero
属性。(click)
事件绑定,当用户点击英雄的名词时调用组件的selectHero
方法。双向数据绑定是第四个重要的数据绑定,在简单的符号里使用
ngModel
指令来连接属性和绑定事件。在HeroListComponent
的模板中虽然没有双向绑定的例子,但是可以参考下面的代码:在双向绑定中,一个数据属性的值从组件中传给 input box 作为属性绑定;当用户改变 input box 的值,这个值将回传给组件,重新设置属性为最新的值,作为事件绑定。
Angular 会在每个 JavaScript 的事件循环(event cycle)中一次性处理所有的数据绑定,从应用组件树的根组件优先开始处理。
目前我们还不知道所有的细节,但是通过这个例子可以非常清晰地意识到数据绑定在模板和组件的交流中扮演重要的角色...
...以及父组件和子组件之间。
指令
Angular 模板是动态的。当 Angular 通过所给的指令来渲染 DOM。
一个指令是一个拥有指令元数据的类。在 TypeScript 中使用
@Directive
修饰器将元数据和类相关联。(未完待续)
服务
『服务』是一个宽泛的范畴,封装了应用所需要的任意值,函数和特性。
几乎所有的事物都可以是一个服务。服务是一个典型的拥有明显意图的类,胜任一些指定的任务。
例如:
关于 Angular 的服务没有什么特别的地方。Angular 自身并没有服务的定义,也没有服务的基础类。
服务是 Angular 应用的基础。
这里有一个将日志打印到控制台的服务类(app/logger.service.ts):
(未完待续)
The text was updated successfully, but these errors were encountered: