亮点
- 脚手架
- 服务端渲染
- 移动和桌面兼容
初识
-
- 安装angular-cli
- npm install -g angular-cli@latest
- 安装angular-cli
-
- 因为angular-cli是用typescript写的,安装typescript typings:
- npm install -g typescript typings
- 因为angular-cli是用typescript写的,安装typescript typings:
-
- 如果安装出现失败时试一下这个命令
- npm cache clean –force
- 删除缓存目录下的所有数据。从 npm@5 开始,为了保证缓存数据的有效性和完整性,需要加上 –force 参数。
- 如果安装出现失败时试一下这个命令
差值表达式{{}}
- 双大括号是Angular中的插值表达式绑定语法
- 单向数据绑定的一种形式
[{ngModel}]=”属性名称”
- Angular 2 中 ==[] 实现了模型到视图的数据绑定,() 实现了视图到模型的事件绑定。两个结合在一起 [()] 就实现了双向绑定==。
- [(ngModel)]是一个Angular语法,用与把hero.name绑定到输入框中。 它的数据流是双向的:从属性到输入框,并且从输入框回到属性。
*ngFor=”let item of arry”
- ngFor的*前缀表示 < li > 及其子元素组成了一个主控模板。
- 循环
(click)=”onSelect(hero)” 点击事件
- (事件名称)=”点击事件函数名(参数)”
*ngIf=”true/false”
[class.selected]=”hero === selectedHero”
当hero === selectedHero时 会给此标签添加selected这个类样式
属性绑定
<img [src]="imgUrl" />
- [属性]=’变量名’
样式绑定
<span [class.stylename]="isTrue" ></span>
- [class.样式类名]=”变量(true/false)”
组件
- 在类中定义组件的应用逻辑,为视图提供支持。 组件通过一些由属性和方法组成的 API 与视图交互。
- 装饰器 组件元数据装饰器
组件的必要素
- 装饰器@Component()
- 模板Template
- 控制器Controller
- 模板和控制器通过数据绑定联系
import { Component } from "@angular/core";
@Component({
selector:'hero-detail'
})
export class HeroDetailComponent{
}
- 要定义一个组件,总是要先导入符号Component。
- @Component装饰器为组件提供了Angular元数据。 CSS选择器的名字hero-detail会匹配元素的标签名,用于在父组件的模板中标记出当前组件的位置。
- 总是export这个组件类,因为你必然会在别处import它。
父组件像子组件传值 输入属性
<hero-detail [hero]="selectedHero"></hero-detail>
- 在等号的左边,是方括号围绕的hero属性,这表示它是属性绑定表达式的目标。
- 我们要绑定到的目标属性必须是一个输入属性,否则Angular会拒绝绑定,并抛出一个错误。
输入属性:
- 引入Input
import { Component, Input } from '@angular/core'; export class HeroDetailComponent { @Input() hero: Hero; }
声明组件
- 每个组件都必须在一个(且只有一个)Angular模块中声明。
- 倒入模块:import { HeroDetailComponent } from ‘./hero-detail.component’;
- 将组件添加到该模块的declarations数组中:declarations: [AppComponent,HeroDetailComponent]
- 通常,declarations数组包含应用中属于该模块的组件、管道和指令的列表。 组件在被其它组件引用之前必须先在一个模块中声明过。
服务
- 命名规则:
- 遵循的文件命名约定是:服务名称的小写形式(基本名),加上.service后缀。 如果服务名称包含多个单词,我们就把基本名部分写成中线形式 (dash-case)。 例如,SpecialSuperHeroService服务应该被定义在special-super-hero.service.ts文件中。
- 可注入的服务 导入了 Angular 的Injectable函数,并作为@Injectable()装饰器使用这个函数。
import { Injectable } from "@angular/core";
@Injectable()
export class HeroService{
}
- Service可以从任何地方获取Hero数据 —— Web服务、本地存储或模拟数据源
import { Injectable } from "@angular/core";
import {Hero} from './hero';
import { HEROES } from "./mock-heroes";
@Injectable()
export class HeroService{
// 添加一个桩方法
getHeroes():Hero[] {
return HEROES;
}
}
- 注入服务
- 添加一个构造函数,并定义一个私有属性。
- 添加组件的providers元数据。
@Component({
providers:[服务名称]
})
export class AppComponent {
// 构造函数
constructor(private heroService:HeroService){}
}
- 构造函数:构造函数是为了简单的初始化工作而设计的,例如把构造函数的参数赋值给属性。
生命周期函数
- 组件生命周期的几个关键时间点:刚创建时、每次变化时,以及最终被销毁时
- 每个接口都有唯一的一个方法。只要组件实现了这个方法,Angular 就会在合适的时机调用它。
- ngOnInit
接口
- OnInit
- OnDestroy
- DoCheck
- OnChanges
- AfterContentInit
- AfterContentChecked
- AfterViewInit
- AfterViewChecked
函数名
- ngOnChanges - 当输入/输出绑定的值改变时调用
- ngOnInit - 在第一次 ngOnChanges 后调用【组件实例化之后会调用一次】
- ngDoCheck - 自定义的方法,检测和处理值的改变
- ngAfterContentInit - 在组件内容初始化之后调用
- ngAfterContentChecked - 组件每次检查内容时调用
- ngAfterViewInit - 组件相应的视图初始化之后调用
- ngAfterViewChecked - 组件每次检查视图时调用
- ngOnDestroy - 指令销毁前调用。
异步请求
- 可以使用承诺(Promise),它是一种异步技术,我们得修改这个实现,把它变成基于承诺的,并在承诺的事情被解决时再行动。 一旦承诺的事情被成功解决(Resolve)
export class HeroService {
getHeroes(): Promise<Hero[]> {
return Promise.resolve(HEROES);
}
}
- 把回调函数作为参数传给承诺对象的then方法
getHeroes(): void {
this.heroService.getHeroes().then(heroes => this.heroes = heroes);
}
- 我们可以模拟慢速连接。导入Hero类,并且在HeroService中添加如下的getHeroesSlowly()方法:
getHeroesSlowly(): Promise<Hero[]> {
return new Promise(resolve => {
// Simulate server latency with 2 second delay
setTimeout(() => resolve(this.getHeroes()), 2000);
});
}
- 从HeroesComponent的providers数组中移除了HeroService服务, 并把它添加到AppModule的providers数组中。 这个改动创建了一个HeroService的单例对象,应用中的所有组件都可以使用它
@NgModule({
providers:[HeroService]
})
路由
- Angular 路由器是一个可选的外部 Angular NgModule,名叫RouterModule。 路由器包含了多种服务(RouterModule)、多种指令(RouterOutlet、RouterLink、RouterLinkActive)、 和一套配置(Routes)。
- 打开index.html,确保它的区顶部有一个元素(或动态生成该元素的脚本)。【这个标签是必须的,代表基地址】
配置路由
- 在 app.module.ts文件中引入路由模块并进行配置
import { RouterModule } from '@angular/router'; import { HeroesComponent } from "./heroes.component"; @NgModule({ imports:[ RouterModule.forRoot([ { path: 'heroes', component: HeroesComponent } ]) ] })
- Path: 路由器会用它来匹配浏览器地址栏中的地址
- Component: 导航到此路由时,路由器需要创建的组件
- 路由出口
<router-outlet> </router-outlet>
- 路由链接
<a routerLink="/heroes">Heroes</a>
- 重定向路由
{
path: '',
redirectTo: '/dashboard',
pathMatch: 'full'
},
带参数路由
- /detail/:id
- URL中的/detail/部分是固定不变的,但结尾的数字id部分会随着英雄的不同而变化。 我们要把路由中可变的那部分表示成一个参数 (parameter) 或令牌 (token) ,代表英雄的id。
- 路径中的冒号 (:) 表示:id是一个占位符,当导航到这个HeroDetailComponent组件时,它将被填入一个特定英雄的id
{ path: 'detail/:id', component: HeroDetailComponent },
点击路由到详情页
- 修改之前的detailsComponent文件
- 从ActivatedRoute服务的可观察对象params中取得id参数, 并通过HeroService服务获取具有这个指定id的英雄数据。
- 先倒入
import { Component, Input, OnInit } from '@angular/core'; import { ActivatedRoute, ParamMap } from '@angular/router'; import { Location } from '@angular/common'; import { HeroService } from './hero.service';
- switchMap是angular官方给的拿取url参数的方法,也是需要预先导入才可以使用:
import 'rxjs/add/operator/switchMap';
- 然后注入ActivatedRoute和HeroService服务到构造函数中,将它们的值保存到私有变量中:
- JavaScript 的 (+) 操作符把路由参数的值转成数字。
ngOnInit(): void { this.route.paramMap .switchMap((params: ParamMap) => this.heroService.getHero(+params.get('id'))) .subscribe(hero => this.hero = hero); }
- 注意switchMap运算符如何将可观察的路由参数中的 id 映射到一个新的Observable, 即HeroService.getHero()方法的结果。如果用户在 getHero 请求执行的过程中再次导航这个组件,switchMap 再次调用HeroService.getHero()之前, 会取消之前的请求。
???????
routerLinkActive指令
- Angular路由器提供了routerLinkActive指令,我们可以用它来为匹配了活动路由的 HTML 导航元素自动添加一个 CSS 类
<a routerLink="/dashboard" routerLinkActive="active">Dashboard</a>
名词
- 路由
- 子路由
- 保护路由
- 辅助路由
- 视图状态集合
基础知识
- ng new router –routing
- webstorm中,倒入某个模块的快捷键command+1
- path: ” 冒号中不要在开头写/
- RoutLink中要写/开头,相当于路由到跟路由,=[“/router”] ,是数组
- 显示不存在多路由页面时候配置路由
{path:'**',component:code404Component}
- 路由器采用先匹配者优先,所以**陪在最后