详解Angular的8个主要构造块


Posted in Javascript onJune 20, 2017

Angular 主要分为八大构造块(也就是八个核心概念):模块 (module)、组件 (component)、模板 (template)、元数据 (metadata)、数据绑定 (data binding)、指令 (directive)、服务 (service)、依赖注入 (dependency injection)。其中,最核心的一个概念就就组件。

1. 模块 (module)

Angular 应用是模块化的,并且 Angular 有自己的模块系统,它被称为 Angular 模块或 NgModules。

每个Angular应用至少有一个模块(根模块),习惯上命名为AppModule。

根模块在一些小型应用中可能是唯一的模块,大多数应用会有很多特性模块,每个模块都是一个内聚的代码块专注于某个应用领域、工作流或紧密相关的功能。

Angular 模块(无论是根模块还是特性模块)都是一个带有@NgModule装饰器的类。

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

// src/app/app.module.ts

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 { }

其中重要的属性是:

  1. declarations - 声明本模块中拥有的视图类。Angular 有三种视图类:组件、指令、管道;
  2. exports - declarations 的子集,可用于其它模块的组件;
  3. imports - 本模块声明的组件模板需要的类所在的其它模块。用来导入其他自定义模块,第三方插件模块;
  4. providers - 服务的创建者,并加入到全局服务列表中,可用于应用任何部分;
  5. bootstrap - 指定应用的主视图(称为根组件),它是所有其它视图的宿主。只有根模块才能设置bootstrap属性。通常在main.ts中引导AppModule,这样platformBrowserDynamic().bootstrapModule(AppModule)

2. 组件 (component)

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

下面是一个组件的简单例子:

// src/app/hero-list.component.ts

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; }
}

3. 模板 (template)

模板就是HTML文件,但是不是标准的HTML文件,它使用了一些模板语法,模板语法使模板有了自己的逻辑关系,并能够实现和组件的简单数据交互。

下面是一个简单的模板:

// src/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>

通常使用ng g component my-comoponent命令产生一个组件包含四个文件:

my-comoponent.css      // 样式文件
my-comoponent.thml      // 模板
my-comoponent.spec.ts    // 测试文件
my-comoponent.ts      // 这是组件? 通常我们认为这四个文件组成一个组件

4. 元数据 (metadata)

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

其实,在Angular中每个组件只是一个类,但是我们可以通过装饰器来附加元数据告诉Angular这是一个组件。

下面就是HeroListComponent的一些元数据。

// src/app/hero-list.component.ts (metadata)

@Component({  // @Component 将后面的 HeroListComponent 类标记为一个组件
 selector:  'hero-list',
 templateUrl: './hero-list.component.html',
 providers: [ HeroService ]
})
export class HeroListComponent implements OnInit {
/* . . . */
}

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

@Component的配置项包括:

  1. selector: CSS选择器,它告诉Angular在父级HTML中查找<hero-list>标签,创建并插入该组件。 例如,如果应用的HTML 包含<hero-list></hero-list>, Angular就会把HeroListComponent的一个实例插入到这个标签中;
  2. templateUrl:组件HTML 模板的模块相对地址;
  3. providers - 组件所需服务的依赖注入提供商数组。 这是在告诉 Angular:该组件的构造函数需要一个HeroService服务,这样组件就可以从服务中获得英雄数据。

到这里你应该可以明白:模板、元数据和组件共同描绘出这个视图。

5. 数据绑定 (databinding)

数据绑定是Angular中最常用的数据处理模式。数据绑定在模板与对应组件的交互中扮演了重要的角色,在父组件与子组件的通讯中也同样重要。

下面是一个简单的例子:

// src/app/hero-list.component.html 

<li>{{hero.name}}</li>
<hero-detail [hero]="selectedHero"></hero-detail>
<li (click)="selectHero(hero)"></li>
  1. {{hero.name}}插值表达式在<li>标签中显示组件的hero.name属性的值;
  2. [hero]属性绑定把父组件HeroListComponent的selectedHero的值传到子组件HeroDetailComponent的hero属性中;
  3. (click) 事件绑定在用户点击英雄的名字时调用组件的selectHero方法。

Angular默认没有双向绑定,但是,官方推荐这样来实现双向绑定:

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

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

6. 指令 (directive)

由于Angular模板是动态的,所以你需要通过指令实现对DOM的转换。(组件是一个带模板的指令;@Component装饰器实际上就是一个@Directive装饰器,只是扩展了一些面向模板的特性。 )

指令分为两种:结构指令、属性指令。

a. 结构指令: 通过在 DOM 中添加、移除和替换元素来修改布局。

下面是一个简单的内置结构指令的例子:

<!-- src/app/hero-list.component.html (structural) -->

<li *ngFor="let hero of heroes"></li>
<hero-detail *ngIf="selectedHero"></hero-detail>
  1. *ngFor告诉 Angular 为heroes列表中的每个英雄生成一个<li>标签。
  2. *ngIf表示只有在选择的英雄存在时,才会包含HeroDetail组件。

b. 属性指令:修改一个现有元素的外观或行为。

简单例子:

<!-- src/app/hero-detail.component.html -->
<input [(ngModel)]="hero.name">

7. 服务 (service)

服务是一个广义范畴,包括:值、函数,或应用所需的特性。几乎任何东西都可以是一个服务。 典型的服务是一个类,具有专注的、明确的用途。它应该做一件特定的事情,并把它做好。

例如:

  1. 日志服务
  2. 数据服务
  3. 消息总线
  4. 税款计算器
  5. 应用程序配置

组件类应保持精简。组件本身不从服务器获得数据、不进行验证输入,也不直接往控制台写日志。 它们把这些任务委托给服务。所以说服务是跑腿的,服务一般用来处理业务逻辑,被注入在组件当中,服务是全局单例的。也就是说注入到所有组件中的服务是同一个。

一个简单的例子:

// src/app/hero.service.ts 

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;
 }
}

8. 依赖注入 (denpendency injection)

“依赖注入”是提供类的新实例的一种方式,还负责处理好类所需的全部依赖。大多数依赖都是服务。 Angular 使用依赖注入来提供新组件以及组件所需的服务。

来看注入方式:

// src/app/hero-list.component.ts

constructor(private service: HeroService) { }

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

通常我们将服务声明在根模块,以便在整个应用中使用这个服务。

// src/app/app.module.ts

providers: [
 BackendService,
 HeroService,
 Logger
],

也可以在其他组件中声明服务,那么这个服务只能用于当前组件。把它注册在组件级表示该组件的每一个新实例都会有一个服务的新实例。

// src/app/hero-list.component.ts

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

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

Javascript 相关文章推荐
javascript字典探测用户名工具
Oct 05 Javascript
Jquery实现地铁线路指示灯提示牌效果的方法
Mar 02 Javascript
JavaScript 里的类数组对象
Apr 08 Javascript
JavaScript 实现完美兼容多浏览器的复制功能代码
Apr 28 Javascript
javaScript实现滚动新闻的方法
Jul 30 Javascript
分享自己用JS做的扫雷小游戏
Feb 17 Javascript
$.browser.msie 为空或不是对象问题的多种解决方法
Mar 19 Javascript
JS 组件系列之Bootstrap Table 冻结列功能IE浏览器兼容性问题解决方案
Jun 30 Javascript
详解JavaScript中的六种错误类型
Sep 21 Javascript
详解Vue文档中几个易忽视部分的剖析
Mar 24 Javascript
vue拦截器实现统一token,并兼容IE9验证功能
Apr 26 Javascript
基于VSCode调试网页JavaScript代码过程详解
Jul 20 Javascript
vue之数据交互实例代码
Jun 20 #Javascript
jquery加载单文件vue组件的方法
Jun 20 #jQuery
Angular.JS中select下拉框设置value的方法
Jun 20 #Javascript
原生js二级联动效果
Jun 20 #Javascript
angularjs下拉框空白的解决办法
Jun 20 #Javascript
JS使用ActiveXObject实现用户提交表单时屏蔽敏感词功能
Jun 20 #Javascript
20行js代码实现的贪吃蛇小游戏
Jun 20 #Javascript
You might like
简单示例AJAX结合PHP代码实现登录效果代码
2008/07/25 PHP
PHP程序员必须知道的两种日志实例分析
2020/05/14 PHP
准确获得页面、窗口高度及宽度的JS
2006/11/26 Javascript
javascript 支持ie和firefox杰奇翻页函数
2008/07/22 Javascript
javascript中实现兼容JAVA的hashCode算法代码分享
2020/08/11 Javascript
分享33个jQuery与CSS3实现的绚丽鼠标悬停效果
2014/12/15 Javascript
asp.net+js实现金额格式化
2015/02/27 Javascript
JS选中checkbox后获取table内一行TD所有数据的方法
2015/07/01 Javascript
JS实现自定义简单网页软键盘效果代码
2015/11/05 Javascript
jQuery之简单的表单验证实例
2016/07/07 Javascript
JavaScript中push(),join() 函数 实例详解
2016/09/06 Javascript
angular实现spa单页面应用实例
2017/07/10 Javascript
vue.js todolist实现代码
2017/10/29 Javascript
详解Nodejs mongoose
2018/06/10 NodeJs
关于TypeScript模块导入的那些事
2018/06/12 Javascript
详解微信小程序胶囊按钮返回|首页自定义导航栏功能
2019/06/14 Javascript
原生js实现下拉选项卡
2019/11/27 Javascript
Vue插件之滑动验证码用法详解
2020/04/05 Javascript
《javascript设计模式》学习笔记一:Javascript面向对象程序设计对象成员的定义分析
2020/04/07 Javascript
vue 监听 Treeselect 选择项的改变操作
2020/08/31 Javascript
Vue实现多页签组件
2021/01/14 Vue.js
[51:36]EG vs VP 2018国际邀请赛淘汰赛BO3 第一场 8.24
2018/08/25 DOTA
[42:06]2019国际邀请赛全明星赛 8.23
2019/09/05 DOTA
python原始套接字编程示例分享
2014/02/21 Python
编写Python脚本使得web页面上的代码高亮显示
2015/04/24 Python
HTML中使用python屏蔽一些基本功能的方法
2017/07/07 Python
Python基于Matplotlib库简单绘制折线图的方法示例
2017/08/14 Python
Python实现串口通信(pyserial)过程解析
2019/09/25 Python
Python进行统计建模
2020/08/10 Python
Python 中的函数装饰器和闭包详解
2021/02/06 Python
美国领先的户外服装与装备用品店:Moosejaw
2016/08/25 全球购物
古驰英国官网:GUCCI英国
2020/03/07 全球购物
《胡杨》教学反思
2014/02/16 职场文书
初中生操行评语大全
2014/04/24 职场文书
公司的门卫岗位职责
2014/09/09 职场文书
先进班组事迹材料
2014/12/25 职场文书