Angular 是一个用 HTML 和 TypeScript 构建客户端应用的平台与框架。 Angular 自己使用 TypeScript
写成的。它将核心功能和可选功能做为一组 TypeScript 库进行实现,你能够把它们导入你的应用中。
一:模块css
NgModule 为一个组件集声明了编译的上下文环境,NgModule 能够将其组件和一组相关代码(如服务)关联起来,造成功能单元每一个 Angular 应用都有一个根模块,一般命名为 AppModule。根模块提供了用来启动应用的引导机制。
一个应用一般会包含不少功能模块。html像 JavaScript 模块同样,NgModule 也能够从其它 NgModule 中导入功能,并容许导出它们本身的功能供其它
NgModule 使用。 好比,要在你的应用中使用路由器(Router)服务,就要导入 Router 这个 NgModule。npm
export class AppModule { } //导出 import { AppModule } from './app/app.module'; //导入
这项技术还能让你得到按需加载模块的优势,以尽量减少启动时须要加载的代码体积。NgModule 是一个带有 @NgModule 装饰器的类,@NgModule 装饰器是一个函数,它接受一个元数据对象,该对象的属性用来描述这个模块bootstrap
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; @NgModule({ imports: [ BrowserModule ], providers: [ Logger ], declarations: [ AppComponent ], exports: [ ], bootstrap: [ AppComponent ] }) export class AppModule { }
解释浏览器
declarations(可声明对象表)—— 声明属于本 NgModule 的组件、指令、管道。 exports(导出表) —— 那些能在其它模块的组件模板中使用的可声明对象的子集,为空是由于根模块没有任何理由导出任何东西,由于其它模块永远不须要导入根模块。 imports(导入表) —— 导入其余模块 providers —— 定义服务,这些服务能被本应用中的任何部分使用。(你也能够在组件级别指定服务提供商,这一般是首选方式。在这里面定义以后在组件里面只须要注入不须要在组件内定义了) bootstrap —— 应用的主视图,称为根组件。它是应用中全部其它视图的宿主。只有根模块才应该设置这个 bootstrap 属性。
NgModule与组件的关系:app
根模块总会有一个根组件,并在引导期间建立它,
好比前面介绍的元数据bootstrap中定义的AppComponent就是 AppModule的根组件框架
任何模块都能包含任意数量的组件,这些组件能够经过路由器加载,也能够经过模板建立。属于这个 NgModule
的组件会共享这个模块提供的同一个编译上下文环境。
angular自带的库ide
Angular 自带了一组 JavaScript 模块,你能够把它们当作库模块。每一个 Angular 库的名称都带有 @angular
前缀。 使用 npm install 包管理器安装它们,并使用 JavaScript 的 import 语句导入其中的各个部分。
import { Component } from '@angular/core'; //从 @angular/core 库中导入 Component 装饰器 import { BrowserModule } from '@angular/platform-browser'; //从 Angular 库中导入 Angular 模块:这个代码从 platform-browser 库中导入了 BrowserModule 模块
NgModule 和 JavaScript 的模块函数
这两种模块系统不一样但互补。你能够同时使用 Angular 和 JavaScript 的这两种模块系统。 虽然这两种模块系统容易混淆(它们共享了一样的词汇 import 和export)
二:组件布局
下面的例子中就是 HeroListComponent 的基础元数据:
@Component({ selector: 'app-hero-list', templateUrl: './hero-list.component.html', providers: [ HeroService ] }) export class HeroListComponent implements OnInit { /* . . . */ }
组件控制视图上的一小片区域,视图都是由一个个组件所组成和控制的组件经过一些由属性和方法组成的 API 与视图交互。
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; } }
好比上面的组件就由heroes、selectedHero属性以及 selectHero()方法与视图进行数据交互的
每一个 Angular 应用都至少有一个组件,也就是根组件---AppComponent,每一个组件都会定义一个类,其中包含应用的数据和逻辑@Component 装饰器代表紧随它的那个类是一个组件,并提供模板和该组件专属的元数据。
模板与视图
模板就是一种 HTML,它会告诉 Angular 如何渲染该组件模板很像标准的 HTML,可是它还包含 Angular 的模板语法,你的模板可使用数据绑定加粗样式**来协调应用和 DOM
中的数据,使用管道在显示出来以前对其进行转换,使用指令来把程序逻辑应用到要显示的内容上。**
<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> <app-hero-detail *ngIf="selectedHero" [hero]="selectedHero"></app-hero-detail> 上面的例子使用了典型的 HTML 元素,好比 <h2> 和 <p>,还包括一些 Angular 的模板语法元素,如 *ngFor(指令),{{hero.name}}(数据绑定),click(数据绑定)、[hero] (数据绑定)和 <app-hero-detail>(组件的子组件)
1:数据绑定
Angular 支持双向数据绑定数据绑定标记有四种形式。每种形式都有一个方向 —— 从组件到 DOM、从 DOM 到组件或双向
<li>{{hero.name}}</li> <app-hero-detail [hero]="selectedHero"></app-hero-detail> <li (click)="selectHero(hero)"></li> <input [(ngModel)]="hero.name"> 分析: 1:{{}}:插值表达式 从组件---DOM 2:[hero] = ''selectedHero'' 属性绑定,把父组件 HeroListComponent 的 selectedHero 的值传到子组件 HeroDetailComponent 的 hero 属性中。从组件---DOM 3:(click)=''selectHero(hero)''事件绑定 从DOM---组件 4:[(ngModel)] = ''hero.name'' 双向绑定 从DOM<>组件
在双向绑定中, 数据属性值经过属性绑定 从组件流到输入框。 用户的修改经过事件绑定流回组件,把属性值设置为最新的值。数据绑定在模板及其组件之间的通信中扮演了很是重要的角色,它对于父组件和子组件之间的通信也一样重要。
2:管道
带有 @Pipe 装饰器的类中会定义一个转换函数,用来把输入值转换成供视图显示用的输出值。Angular 自带了不少管道,好比 date 管道和 currency 管道,你也能够本身定义一些新管道。
语法:{{value_name| pipe_name}}
3:指令
Angular 的模板是动态的。当 Angular 渲染模板的时候,会根据指令给出的指示对 DOM 进行转换。 指令就是一个带有
@Directive 装饰器的类。组件从技术角度上说就是一个指令,除组件外,还有两种指令:结构型指令和属性型指令。
<1结构型指令
结构型指令经过添加、移除或替换 DOM 元素来修改布局
<li *ngFor="let hero of heroes"></li> <app-hero-detail *ngIf="selectedHero"></app-hero-detail>
<2属性型指令
属性型指令会修改现有元素的外观或行为。 在模板中,它们看起来就像普通的 HTML 属性同样,所以得名“属性型指令”ngModel 指令就是属性型指令的一个例子,它实现了双向数据绑定。 ngModel 修改现有元素(通常是 <input>)的行为:设置其显示属性值,并响应 change 事件。Angular 还有不少预约义指令,它们或者修改布局结构(好比 ngSwitch),或者修改 DOM 元素和组件的某些方面(好比 ngStyle 和 ngClass)。
<input [(ngModel)]="hero.name">
三:服务与依赖注入
<1:服务
好比你写了一个公共的方法,这个方法将在不少组件中用到,你就能够把这个公共方法写进一个服务里面,到时候只须要在不一样组件引入这个服务就好,我理解的服务就是服务组件的类,Angular 把组件和服务区分开,以提升模块性和复用性。对于与特定视图无关并但愿跨组件共享的数据或逻辑,能够建立服务类
服务类的定义一般紧跟在 “@Injectable” 装饰器以后
该装饰器提供的元数据可让你的服务做为依赖被注入到客户组件中。
下面是一个服务类的范例,用于把日志记录到浏览器的控制台:
export class Logger { log(msg: any) { console.log(msg); } error(msg: any) { console.error(msg); } warn(msg: any) { console.warn(msg); } }
服务也能够依赖其它服务
<2:依赖注入(DI)
你能够把一个服务注入到组件中,让组件类得以访问该服务类,在 Angular 中,要把一个类定义为服务,就要用 @Injectable
装饰器来提供元数据,以便让 Angular 能够把它做为依赖注入到组件中
constructor(private service: HeroService) { }
对于任何服务,你必须至少注册一个提供商,你也能够为特定的模块或组件注册提供商。要注册提供商,就要在服务的 @Injectable 装饰器中提供它的元数据providedIn,或者在@NgModule 或 @Component 的元数据providers中。
@Injectable({ providedIn: 'root', })
当你在组件级注册提供商时,你会为该组件的每个新实例提供该服务的一个新实例。 要在组件级注册,就要在 @Component 元数据的
providers 属性中注册服务提供商。
@Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], providers:[] })
当你使用特定的 NgModule 注册提供商时,该服务的同一个实例将会对该 NgModule 中的全部组件可用。要想在这一层注册,请用
@NgModule 装饰器中的 providers 属性
@NgModule({ declarations: [ AppComponent, ], imports: [ BrowserModule, ], providers: [], bootstrap: [AppComponent] })
五:路由
它的工做模型基于人们熟知的浏览器导航约定不过路由器会把相似 URL 的路径映射到视图而不是页面,当用户执行一个动做时(好比点击连接),本应该在浏览器中加载一个新页面,可是路由器拦截了浏览器的这个行为,并显示或隐藏一个视图层次结构。
若是路由器认为当前的应用状态须要某些特定的功能,而定义此功能的模块还没有加载,路由器就会按需惰性加载此模块。
这五个概念会有详细的教程。。。