Angular 2应用的8个主要构造块有哪些


Posted in Javascript onOctober 17, 2016

前面的话:最近空余时间在学 Angular 2,国庆节的时候看了官网的quickstart,还写了一篇文章,只是一个hello world demo。后面继续看了它的一个项目教程,刚开始还可以跟上,当后面就比较混乱了。的确,对于新手来讲,要了解一个框架还是比较麻烦的。所以停止项目,开始看看 angular 的整体框架是如何的,联系项目,分析下,慢慢来。

学习链接:中文官网

正文开始:

angular 应用:用带 angular 拓展语法的 HTML 写模板,用组件类管理这些模板,用服务添加应用逻辑,在模块中打包发布组件与服务。通过引导 根模块启动应用。 angular 在浏览器中接管、展现应用的内容,并根据我们提供的操作指令响应用户的交互。

这几个名词很重要,贯穿angular应用开发。

angular 应用的 8个主要构造块:

模块modules
组件components
模板template
元数据metadata
数据绑定data binding
指令directive
服务services
依赖注入dependency injection

模块

angular 应用是模块化的,有自己的模块系统,叫做 angular 模块/NgModules。

到底模块是什么?在angular里模块化意味着什么?

angular 应用至少有一个模块(根模块),称为 AppModule。

大多数应用都有很多其它的 特性模块,它们由一组领域类、工作流、或紧密相关的功能聚合形成。

angular的所有模块都是一个带有 @NgModule 装饰器的类。

angular的模块是类!!!

装饰器是用来修饰JavaScript类的函数。负责把元数据附加到类上。

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

declarations(声明):本模块中拥有的视图类。angular 有三种视图类:组件、指令、管道。
exports:declarations的子集,可用于其它模块中的组件模板。
imports:本模块组件模板中需要由其他模板导出的类。
providers:服务的创建者。本模块把它们加入全局的服务表中,让他们在应用中的任何部分都可被访问到。
bootstrap:标识出应用的主视图(根组件)。只有根模块才可设置此属性。

下面是一个简单的根模块:

// app.module.ts
import { NgModule }   from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

// @NgModle 装饰器函数,接受一个对象,对象有几个属性
@NgModule({
 imports:   [ BrowserModule ],
 providers:  [ Logger ],
 declarations: [ AppComponent ],
 exports:   [ AppComponent ],
 bootstrap:  [ AppComponent ]
})

// AppComponent 的 export 语句导出,根模块不需要导出,其他组件不需导入根模块。
export class AppModule { }

引导根模块来启动应用。在 main.ts 文件中引导 AppModule:

// app/main.ts
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
// 从app.module 文件导入了 AppModule
import { AppModule } from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule);

此时,项目只有 app/app.module.ts 文件和 app/main.ts ,前者定义了应用的根模块,后者引用它来启动应用。

Angular 模块与JavaScript模块比较:

JavaScript的模块化是分文件导入的,各文件就是各模块。

Angular 模块(用 @NgModule 装饰的类)是Angular的基础特性。

JavaScript的模块系统管理一组JavaScript对象。

在JavaScript中,每个文件就是一个模块,该文件中定义的对象从属于该模块。通过 export 关键字,可以把它的某些对象声明为公开。别的模块可以使用 import 语句访问公开对象。

JavaScript的这个特性很有用。
export 关键字声明为公开,import 语句访问公开对象。

在 Angular 里这两种都会用到,从上面的两个个文件里,可以看到。

模块库

上面所说,Angular 用到了 JavaScript模块,所以它的JS模块就是库模块,JS文件库。

Angular 库的名字都以 @angular 前缀,可以使用 npm 包管理工具安装,并如上面的 import 语句可以访问它们中的对象。

这点很好理解,Angular 本来就是依托于JS实现的单页面框架,所以它本身还是需要丰富的JS库的。
比如,从 @angular/core 库导入 Component 装饰器:

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

使用JavaScript导入语句从Angular 库中导入 Angular 的某些模块。

import { BrowserModule } from '@angular/platform-browser';

在上面根模块的代码中,应用模块需要 BrowserModule 的某些素材,所以把它加入 @NgModule 元数据的 imports 中:

imports :[ BrowserModule ];

我们看看基本的@angular库中有哪些JS模块:

common
compiler
core
forms
http
platform-browser
platform-browser-dynamic
router
upgrade

所以,我们同时使用 Angular 和 JavaScript的模块化系统。

这块的 imports 和 exports 比较混乱,可以自己梳理下。

组件

组件负责控制屏幕上的一小块地方,就是视图。

在类中定义组件的应用逻辑(被用来为视图提供支持)。组件通过一些由属性和方法组成的API与视图交互。

所以说组件是联系视图的。

前面的 export 关键字可以把模块中的类声明为公开的,然后 import 里实现访问。

类里面有许多属性和方法。

模板

通过组件自带的模板来定义视图。模板是以HTML形式存在的,它告诉 Angular 如何渲染组件(视图)。

看一个组件文件的模板:

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

模板看起来就是标准 HTML,它里面有一些非标准HTML的语法。*ngFor、{{hero.name}}、{click}、[hero] 和 <hero-derail> ,它们是 Angular 的模板语法。

所以说,Angular 是通过这种方式来处理 HTML的。

元数据

元数据告诉Angular如何处理一个类。

之前 export 的类里有一些方法和属性,但是怎么处理这个类?

只要把元数据附加到这个类,就意味着这个类是个组件。

在 TypeScript 中,我们用装饰器(decorator)来附加元数据。

分析下面的元数据:

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

@Component装饰器把紧随其后的类标记成了组件类。

在装饰器后面的类就会被转为组件类?

装饰器里的配置项:

moduleId:为与模块相关的URL提供基地址。
这个地址怎么使用的?
selector:CSS 选择器,它告诉 Angular 在父级HTML寻找一个标签,然后创建组件实例并插入标签中。
实现HTML的显示。
templateUrl:组件HTML模板的模块相对地址。
HTML模板的设置位置。
providers:数组,包含组件所依赖的服务所需要的依赖注入提供商。告诉Angular该组件的构造函数需要服务,组件可以从服务获取数据。
某些数据的传递通过服务进行,否则,其他的视图只能控制静态的展示。

@Component 里的元数据会告诉 Angular 如何取得你为组件设定的元数据。

模板、元数据和组件共同描绘出这个视图。

组件就是视图,模板提供HTML的结构性。

数据绑定

如果没有框架,那么一些都需要我们来做。把数据值推送到HTML控件,并把用户的反馈接收转换成动作和值更新显示,你可以使用jQuery来实现这个过程。

Angular 框架实现数据绑定,一种让模板各部分与组件的各部分相互联系的机制。在模板HTML中添加绑定标记,Angular 会连接模板和组件。

意味着,我们刻意自动实现视图数据的更新,因为它绑定了组件,可以实现数据的关联。

看一个示例:

// app/hero-list.component.ts

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

观察到在这个模板HTML里,有一些非标准HTML的字符。

{{hero.name}} 插值表达式:在元素中显示组件的 hero.name属性的值。
[hero] 属性绑定:把父组件的值传到子组件的 hero 属性中。
(click) 事件绑定:当用户点击元素时调用方法。

文件之间的互相关系需要梳理清楚。
双向数据绑定:同时实现属性绑定和事件绑定的功能。看示例:

// app/hero-detail.component.ts

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

数据属性的值会从具有属性绑定的组件传到输入框,事件绑定使用户的修改被传回组件,把属性值设为最新的值。

指令

Angular 模板是动态的。当 Angular 渲染它们时,它会根据指令对DOM进行修改。

就是说解析模板HTML的时候,会解析其中的指令。

指令是一个带有指令元数据的类。

指令是一个类,并且它含有指令源数据。

在TypeScript中,要通过 @Directive 装饰器把元数据附加到类上。

和之前的类的元数据一样,通过 @Component 装饰器把元数据附加到后面的类,编程组件类。这个就是通过 @Directive 装饰器把一些元数据附加到后面的指令类。

结构型指令:通过在DOM中添加、移除、替换元素修改布局。ngFor 、 ngIf。

属性指令:修改现有元素的外观或行为。ngModel

服务

服务分很多种,值、函数、应用所需的特性。

几乎任何东西都可以是一个服务。典型的服务是一个类。

例如:

日志服务
数据服务
消息总线
税款计算器
应用程序配置

组件是最大的服务消费者。

组件的一些操作需要服务提供一些数据。

示例,把日志记录显示到浏览器控制台:

// app/logger.service.ts

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

这些服务使得组件不用去服务器获取数据、进行验证……,这一切都可以通过服务完成。

组件的任务就是提供用户体验,仅此而已!

它介于视图(由模板渲染)和应用逻辑(包括模型)之间。

设计良好的组件为数据绑定提供属性和方法,对它们不重要的事情委托给服务。

依赖注入

依赖注入是提供类的新实例的一种方式,负责处理好类所需的全部依赖(服务)。

Angular 使用依赖注入提供我们需要的组件及组件所需的服务。

Angular 能通过查看构造函数的参数类型,来的值组件所需的服务。

示例:

// app/hero-list.component.ts

constructor(private service: HeroService) { }

构造函数的参数提到了一个服务。

当 Angular 创建组件时,会先为组件所需的服务找一个注入器(Injector)。

注入器是一个维护服务实例的容器,存放着以前创建的实例。如果容器中还没有所请求的服务实例,注入器就会创建一个服务实例,并且添加到容器中,然后把这个服务返回给 Angular。当所有服务都被解析完并返回, Angular 会以这些服务为参数去调用组件的构造函数,这就是依赖注入。

也就是说服务是先于组件被执行的。它先处理所有的服务到一个仓库,然后再处理组件,组件需要哪个服务就从仓库取出来给你。
提供商添加到根模块,在任何地方使用的都是服务的同一个实例:

// app/app.module.ts

providers: [
 BackendService,
 HeroService,
 Logger
],

提供商是确定处理组件之前必须存在所依赖的组件
也可以把它注册到组件层:

// app/hero-list.component.ts

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

添加到装饰器元数据的属性中。

依赖注入的要点:

1、依赖注入渗透在整个Angular框架中
2、注入器是机制的核心
      注入器负责维护一个容器,存放创建过的服务实例
      注入器能使用提供商创建一个新的服务实例
3、提供商是一个用于创建服务的配方。
4、把提供商注册到注入器。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript获得服务器端控件的ID的实现代码
Dec 28 Javascript
做好七件事帮你提升jQuery的性能
Feb 06 Javascript
javascript实现仿腾讯游戏选择
May 14 Javascript
一系列Bootstrap导航条使用方法分享
Apr 29 Javascript
jQuery中的each()详细介绍(推荐)
May 25 Javascript
AngularJS表格详解及示例代码
Aug 17 Javascript
浅谈Angular2 ng-content 指令在组件中嵌入内容
Aug 18 Javascript
JavaScript使用FileReader实现图片上传预览效果
Mar 27 Javascript
使用webpack打包koa2 框架app
Feb 02 Javascript
jquery+css3实现熊猫tv导航代码分享
Feb 12 jQuery
基于jQuery实现的设置文本区域的光标位置
Jun 15 jQuery
vue中使用codemirror的实例详解
Nov 01 Javascript
jQuery表单验证简单示例
Oct 17 #Javascript
jQuery右下角悬浮广告实例
Oct 17 #Javascript
WEB前端实现裁剪上传图片功能
Oct 17 #Javascript
Javascript获取background属性中url的值
Oct 17 #Javascript
JS+HTML5实现的前端购物车功能插件实例【附demo源码下载】
Oct 17 #Javascript
jquery checkbox的相关操作总结
Oct 17 #Javascript
JS动态添加选项案例分析
Oct 17 #Javascript
You might like
WindowsXP中快速配置Apache+PHP5+Mysql
2008/06/05 PHP
PHP使用JSON和将json还原成数组
2015/02/12 PHP
PHP+jQuery+Ajax实现分页效果 jPaginate插件的应用
2015/10/09 PHP
吐槽一下我所了解的Node.js
2014/10/08 Javascript
javascript等号运算符使用详解
2015/04/16 Javascript
JavaScript实现函数返回多个值的方法
2015/06/09 Javascript
使用JavaScript判断手机浏览器是横屏还是竖屏问题
2016/08/02 Javascript
AngularJs  Using $location详解及示例代码
2016/09/02 Javascript
前端框架Vue.js中Directive知识详解
2016/09/12 Javascript
jQuery EasyUI 选项卡面板tabs的使用实例讲解
2017/12/25 jQuery
Angular中使用ng-zorro图标库部分图标不能正常显示问题
2019/04/22 Javascript
javascript中call,apply,callee,caller用法实例分析
2019/07/24 Javascript
vue-next/runtime-core 源码阅读指南详解
2019/10/25 Javascript
Bootstrap实现前端登录页面带验证码功能完整示例
2020/03/26 Javascript
js简单粗暴的发布订阅示例代码
2021/01/23 Javascript
Python实现发送email的几种常用方法
2014/08/18 Python
python使用post提交数据到远程url的方法
2015/04/29 Python
详解Python迭代和迭代器
2016/03/28 Python
python打包压缩、读取指定目录下的指定类型文件
2018/04/12 Python
PyTorch的深度学习入门之PyTorch安装和配置
2019/06/27 Python
python多线程使用方法实例详解
2019/12/30 Python
Pycharm 2020最新永久激活码(附最新激活码和插件)
2020/09/17 Python
配置H5的滚动条样式的示例代码
2018/03/09 HTML / CSS
草莓网英国官网:Strawberrynet UK
2017/02/12 全球购物
英国优质鞋类专家:Robinson’s Shoes
2017/12/08 全球购物
阿迪达斯法国官方网站:adidas法国
2018/03/20 全球购物
wedgwood加拿大官网:1759年成立的英国国宝级陶瓷餐具品牌
2018/07/17 全球购物
Shell编程面试题
2012/05/30 面试题
Jdbc数据访问技术面试题
2012/03/30 面试题
会计自我鉴定范文
2013/10/06 职场文书
自荐信如何“自荐”
2013/10/24 职场文书
卫生系统先进事迹
2014/05/13 职场文书
贸易经济专业自荐书
2014/06/29 职场文书
群众路线教育实践活动调研报告
2014/11/03 职场文书
出国留学单位推荐信
2015/03/26 职场文书
浅谈sql_@SelectProvider及使用注意说明
2021/08/04 Java/Android