Angular2 基础学习。概念性扫盲。
本文地址:http://blog.csdn.net/mingyueyixi/article/details/72904657
撰写此文时,AngularJS已经发展到版本4。本文实际上基于AngularJS4。
知识点:
TypesScript基础:https://git.oschina.net/mingyueyixi/typejs/tree/master/page/00-tsBook
TypeScript 中文网:https://www.tslang.cn/
AngularJS1 官网:https://angularjs.org
AngularJS2 官网:https://angular.io
AngularJS 中文网:https://angular.cn
Angular 应用是由组件组成。 组件由 HTML 模板和组件类组成,组件类控制视图。
AngularJS 是一个 JavaScript 框架。可以被 标签添加到 HTML 中。它的本质就是JavaScript。
其他特性与优点:https://angular.cn/features.html
2009年,Misko Hevery和Adam Abrons 创造了GetAngular。
2012年,谷歌发布Angular1.0。
2016年,谷歌发布Angular2.0正式版。
1和2+的差异有多大?不是青蛙和蟾蜍的差异,而是非洲巨蛙和绿色小树蛙的区别,或者说就如同Java和JavaScript的外表差异一样。
AngularJS2 开始引入微软的TypeScript。许多概念都基于TypeScript。
官方在GitHub
上分别进行维护:
AngularJS1各个版本:https://github.com/angular/angular.js/releases
AngularJS2+各个版本: https://github.com/angular/angular/release
两个官网
:
AngularJS1官网:https://angularjs.org
AngularJS2官网:https://angular.io
题外话
:没有3。但2和4之间并没有基因突变。
CLI:command line interface
命令行界面工具。安装之后可以使用一系列ng
命令来创建项目、添加文件以及执行一大堆开发任务,比如测试、打包和发布。
命令行工具用管理员权限。
使用npm命令安装:
npm install -g @angular/cli
安装成功之后,使用ng命令创建AngularJS项目:
ng new my-app
npm 安装依赖包:
npm install --save
打开服务:
ng serve --open
网络被墙,解决方式:使用管理员权限打开命令行工具,安装时,添加淘宝代理:
npm install -g @angular/cli --registry https://registry.npm.taobao.org
关系图
:
官网这么说:
Learn these building blocks, and you’re on your way.
译文
:学好这些,你就出师了。
题外话
:Ionic2+中,以上知识随处可见,出现得非常频繁。
模块是一种概念。可以参考:CommonJS,AMD,CMD。
但需要注意的是,Angular模块与JavaScript或TypeScript模块的概念不同,Angular有自己的模块系统。并非JavaScript或TypeScript一个文件就是一个模块。
官方说明:
Angular 模块把组件、指令和管道打包成内聚的功能块。
重要概念:
根模块
(root module) 和特性模块
(feature modules)AngularJS模块系统称为Angular Module或NgModule。使用一个装饰器(TypeScript语法)来表现,形式为:@NgModule({//...})
关于装饰器:https://github.com/zhongsp/TypeScript/blob/master/doc/handbook/Decorators.md
如何创建一个模块?使用@NgModule装饰器修饰一个类,并指定装饰器的属性。
具体形式如下面这个根模块:
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 { }
AngularJS模块的内容其实非常丰富,以上仅作概念性扫盲。更多的特性、使用方法,请参考以下内容。
Angular模块 (NgModule): https://angular.cn/docs/ts/latest/guide/ngmodule.html
Angular 模块常见问题: https://angular.cn/docs/ts/latest/cookbook/ngmodule-faq.html
@NgModule({})
NgModule是一个类装饰器(装饰AppModule),它接收一个用来描述模块属性的元数据对象。这个对象有以下几个重要的属性:
declarations
声明本模块中拥有的视图类(组件
、指令
、管道
)exports
导出视图类,使其他模块可以使用。它是declarations 的子集imports
导入本模块依赖的其他模块或路由。(只应该放置)providers
指定模块依赖的服务bootstrap
指定应用的主视图(称为根组件),所有其它视图的宿主(一棵树),Angular 创建它并插入index.html宿主页面。只有根模块才能设置bootstrap属性其中,一些参数的说明:
组件、指令、管道、路由、服务等将在后续说明。
有必要知道。
根模块
的作用:通过引导它来启动应用。
一般,启动应用的文件被命名为app.ts
或main.ts
,内容如下:
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
platformBrowserDynamic().bootstrapModule(AppModule);方法启动根模块,从而使Angular应用运行起来。
以上是即时 (JiT) 编译器动态引导的方式。此处不做展开,更多内容,如预编译器 (AoT - Ahead-Of-Time) 进行静态引导的方式,请参考:https://angular.cn/docs/ts/latest/guide/ngmodule.html
组件负责控制屏幕上的一小块区域,我们称之为视图。它扮演的角色是控制器或视图模型。
组件声明的形式:@Component({})
如何创建一个组件?使用@Component装饰器修饰一个类,并指定装饰器的属性,如selector和template。
比如下面这个根组件:
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'Hello world!';
}
可以看到 @Component装饰器能接受一个配置对象,Angular 会基于这些信息创建和展示组件及其视图。
@Component 配置对象的属性包括:
selector
: CSS 选择器。它使Angular在父级的html中查找一个指定的标签,如’app-root’。使得Angular能够将当前组件的模板插入到父级html中 templateUrl
: 当前html模板地址template
: 使用多行字符串“的形式,在TypeScript文件中直接嵌入html板块providers
: 服务提供者其中的app-root标签具体在哪里? 它在此组件的父级html中,AppComponent已经是根组件,它的父级html是index.html。
Angular 会创建、更新和销毁组件。通过生命周期钩子在组件生命周期的各个时间点上插入自己的操作。关于生命周期钩子:https://angular.cn/docs/ts/latest/guide/lifecycle-hooks.html
它的角色是视图。
就和上述组件中说明的一样,模板就是html块。它有三种使用形式,通过template或templateUrl的形式导入或者直接在html中使用。
模板可以很简单,上述组件代码使用的模板:
app.component.html
<h1>
{{title}}
h1>
{{title}}就是数据绑定。
元有基本、本源的意思。元数据是指描述一个数据的数据。通常一个数据会由其他的数据描述构成,从而形成一个数据结构体,这个结构体的基本单元(数据)就是元数据。
比如:
@Component(
{
xxx:'o|o',
yyy:'o-o'
}
)
export class AppComponent{}
装饰器@Component中的数据是一个JSon,这个JSon被另一些数据描述,这些数据就是元数据。
一种让模板的各部分与组件的各部分相互合作的机制。
有四种数据绑定方式:
在子组件和父组件之间的通讯之中使用:
它们在语法上的差异表现就是括号不同。
<li>{{hero.name}}li>
<hero-detail [hero]="selectedHero">hero-detail>
<li (click)="selectHero(hero)">li>
<input [(ngModel)]="hero.name">
[注] 具体区别可以参考《揭秘Angular2》158~170页
Angular 模板是动态的。当 Angular 渲染它们时,它会根据指令提供的操作对 DOM 进行转换。
指令的类型:
指令实际上不是*ngFor这个短短的关键字一样的字面上的意思,而是一个整体,是一个类。
指令还可以自定义。以下是一个自定义的指令:
import {Directive, ElementRef} from "@angular/core";
@Directive({
selector:'[myCyanLight]'
})
export class ElementLight{
constructor(el:ElementRef) {
el.nativeElement.style.background = 'cyan';
}
}
怎么使用?
以上只做简单介绍,更多参考官方文档:
属性型指令:https://angular.cn/docs/ts/latest/guide/attribute-directives.html
结构型指令:https://angular.cn/docs/ts/latest/guide/structural-directives.html
服务只是一个概念,AngularJS并未作出API层面上的定义。
服务是一个广义范畴,包括:值、函数,或应用所需的特性。几乎任何东西都可以是一个服务,Angular中服务无处不在。
关于这个还是请官方文档来说明:点击查看
一种提供类的实例的方式。
通常一个类可以通过new ClassName来实例化,而“依赖注入”是实例化的一种方式,可以处理好类所需的全部依赖。这些依赖通常是服务。
如何使用?
使用了依赖注入的一个组件:
@Component({
selector: 'xxx',
templateUrl: './yyy.html',
providers: [ LoggerService,TimeService ]
})
export class HorseComponent{
constructor(private logger: LoggerService,private timeService: TimeService) { }
当 Angular 创建HorseComponent组件时,会首先为组件所需的服务LoggerService请求一个注入器 (injector)。如果注入器中不存在LoggerService或TimeService实例,会先创建,并添加到注入器中,当所有实例解析完毕,Angular会将实例注入构造方法中。
通常我们可以把 providers[]
写在根模块,这么做在任何地方都能够使用注入服务的同一个实例。上述示例写在组件层,组件每一个新实例都会伴随新的服务实例。
题外话
:其实以上有不少废话,so 还是看图
转换模板中要显示的数据。
如果一个模板xxx.html:
<p>The hero's birthday is {{ birthday | date:format }}p>
date之前存在|,这代表date是一个管道函数。date:format,format是管道的参数。管道可以接受多个数量的参数,以:分隔。多个管道也可以连在一起,叫链式管道,以|链接。
常用的内置管道有:DatePipe、JsonPipe、UpperCasePipe、LowerCasePipe、DecimalPipe、CurrentPipe、PercentPipe、SlicePipe等。
官方的示例:
import { Component } from '@angular/core';
@Component({
selector: 'hero-birthday2',
template: `
The hero's birthday is {{ birthday | date:format }}
`
})
export class HeroBirthday2Component {
birthday = new Date(1988, 3, 15); // April 15, 1988
toggle = true; // start with true == shortDate
get format() { return this.toggle ? 'shortDate' : 'fullDate'; }
toggleFormat() { this.toggle = !this.toggle; }
}
相关说明:
ng2中,事件绑定形式:(xxxEvent)
date是Angular内置的管道函数。
当内置管道不够用时,需要自定义。
自定义管道及使用方法:
其中,xxx:即管道在html模板中的表现形式,如 远芳侵古道{{inpt | xxx}}
以下定义一个尼玛兽管道:
import {Pipe, PipeTransform} from '@angular/core';
@Pipe({name:'nima'})
export class NimaPipe implements PipeTransform {
transform(value: string, ...args: any[]) {
let retn = "尼玛兽队——"+value;
for (let i = 0;i"-->尼玛兽"+i+"号:"+args[i].toString();
}
return retn;
}
}
接着声明到NgModule中。点击查看
最后使用尼玛兽管道。点击查看
路由(Routing)是导航的另一个名字。路由器(Router)就是从一个视图导航到另一个视图的机制。
const appRoutes : Routes = [
{path:'pipe',component:PipeComponent},
{path:'route',component:RouteComponent}
];
可以在根模块中直接配置:
@NgModule({
imports: [
RouterModule.forRoot(appRoutes)
],
providers: []
})
RouterModule.forRoot(appRoutes)方法创建一个路由模板ModuleWithProviders。
一般,未避免根模块中代码过多,可以将路由的配置抽出,构建一个专门配置路由的模块,在根模块中配置路由模块即可。
使用重新导出功能,构建一个路由模块:点击查看
最后在根模块的@NgModule中,使用import配置路由模块:
app.module.ts
@NgModule({
declarations: [...,路由的组件 ],// 组件、管道、指令
imports: [
...,
AppRouteModule //路由模块
],//模块
providers: [],//服务
bootstrap: [AppComponent]
})
export class AppModule { }
以上仅是路由的简单用法,更多请参考:https://angular.cn/docs/ts/latest/tutorial/toh-pt5.html
另外一些说明
不属于入门级或本次概念性扫盲涉及的知识。
本文使用的资源以及一些示例。
Hello-World: http://git.oschina.net/mingyueyixi/angularjs/tree/master/Hello-World
Hello-Angular: http://git.oschina.net/mingyueyixi/angularjs/tree/master/Hello-Angular
Hello-Http: https://git.oschina.net/mingyueyixi/angularjs/tree/master/Hello-Http