学习资料来源于https://angular.cn/tutorial
根据angular教程"英雄指南"
一、需要完成
1、获取并且显示人才列表
2、编辑选中的人才详情
3、完成不同人才数据之间的导航
二、完成功能
1、用内置指令来显示或隐藏元素,显示人才数据列表
2、创建angular组件显示人才的详情,并显示一个人才的数组
3、为只读数据使用单项数据绑定
4、添加可编辑字段、使用双向数据绑定在更新模型
5、添加方法绑定到用户事件上
6、用户可以在主列表中选中一个人才,并可以在详情视图中编辑他
7、使用管道来格式化数据
8、创建共享的服务来管理这些人才
9、使用路由在不同的视图及其组件之间的导航
第一步
1、ng new myApp使用angular cli创建初始的应用结构
2、
3、{{title}}使用双花括号插值表达式显示数据
第二步:
(ng g class talent添加talent.ts)
1、ng g component components/talent或者ng generate component talents使用CLI创建第二个组件,显示人才列表的视图
2、把talents创建的组件添加到壳组件 AppComponent 中,以便显示它
3、使用UppercasePipe来格式化人才的名字
4、使用ngModel指令实现双向数据绑定
第三步:
1、人才指南应用在一个主从视图中显示了英雄列表
2、用户可以选择一个人才,并查看该英雄的人才
3、使用ngFor显示了一个列表
4、使用ngIf来根据条件包含或排除一段
5、用class绑定来切换css的样式类
第四步:
1、创建一个独立的可复用的talentDetailComponent人才详细组件
2、用属性绑定语法来让父组件 talentsComponent 可以控制子组件 TalentsDetailComponent
3、用@Input装饰器来让talent人才属性可以在外部的talentsComponent 中绑定
第五步:
1、把数据访问逻辑重构到TalentService 类中
2、在根注入器中把TalentService注册为改服务的供应商,以便在其他组件可以注入它
3、使用angular依赖注入机制把它注册到组件中
4、给TalentService中获取数据的方法提供一个异步的函数签名
5、发现Observable以及RxJs库
6、使用RxJS的of()方法返回一个模拟人才数据的可观察对象Observable
7、在组件ngOnInit生命周期钩子中调用TalentService方法
8、你创建了一个 MessageService,以便在类之间实现松耦合通讯
第六步:
功能:
1、添加一个仪表盘视图
2、在人才列表和仪表盘视图之间导航
3、无论在哪个视图中点击一个人才,都会导航到该人才的详情页
4、在邮件中点击一个深链接,会直接打开一个特定人才的详情视图
/****************************************/
1、添加了 Angular 路由器在各个不同组件之间导航
2、你使用一些 链接和一个
3、在 AppRoutingModule 中配置了路由器
4、定义了一些简单路由、一个重定向路由和一个参数化路由
5、在 元素中使用了 routerLink 指令
6、把一个紧耦合的主从视图重构成了带路由的详情视图
7、使用路由链接参数来导航到所选人才的详情视图
8、在多个组件之间共享了 TalentService 服务
第七步:
功能:
1、借助 Angular 的 HttpClient 来添加一些数据持久化特性
2、TalentService 通过 HTTP 请求获取人才数据
3、用户可以添加、编辑和删除人才,并通过 HTTP 来保存这些更改
4、用户可以根据名字搜索人才
/*************************************/
1、添加了在应用程序中使用 HTTP 的必备依赖
2、重构了 TalentService,以通过 web API 来加载人才数据
3、扩展了 TalentService 来支持 post()、put() 和 delete() 方法
4、修改了组件,以允许用户添加、编辑和删除英雄
5、配置了一个内存 Web API
6、学会了如何使用“可观察对象
开始才招聘管理
一、创建人才招聘管理
1、创建项目
ng new ngTalents
2、添加angular-in-memory-web-api
创建完成之后,在package.json文件找到dependencies添加
"@angular/upgrade": "^6.0.0-rc.5",
"angular-in-memory-web-api": "^0.6.0",
添加完之后cnpm install
3、使用双花括号插值表达式显示数据
app.component.ts
title = '人才招聘管理';
app.component.html
清空自动创建的模版
{{title}}
src/styles.css
添加共用样式
h1 {
color: #369;
font-family: Arial, Helvetica, sans-serif;
font-size: 250%;
}
h2, h3 {
color: #444;
font-family: Arial, Helvetica, sans-serif;
font-weight: lighter;
}
body {
margin: 2em;
}
body, input[text], button {
color: #888;
font-family: Cambria, Georgia;
}
* {
font-family: Arial, Helvetica, sans-serif;
}
二、创建人才列表
1、创建人才列表新组件
ng g component components/talents
app/components/talents/talents.component.ts
添加talent属性,用来表示一个名叫 “Mr.1” 的英雄
talent='Mr.1'
talents.component.html
使用双花括号插值表达式显示数据
{{talent}}
app-talents添加到壳组件 AppComponent
src/app/app.component.html
{{title}}
2、人才不止一个人,创建talent,并且添加id和name属性
ng g class talent
src/app/talent.ts添加id和name属性,代码如下
export class Talent {
id:number;
name:string;
}
3、到talents.component.ts人才列表类,导入talent,重构talent='Mr.1'
src/app/components/talents/talents.component.ts修改后代码
import { Component, OnInit } from '@angular/core';
import { Talent } from '../../talent';
@Component({
selector: 'app-talents',
templateUrl: './talents.component.html',
styleUrls: ['./talents.component.css']
})
export class TalentsComponent implements OnInit {
// talent='Mr.1'
talent:Talent={
id: 1,
name: 'Mr.1'
};
constructor() { }
ngOnInit() {
}
}
4、修改人才视图模版
talents.component.html
人才的名字是:{{talent.name}}
人才的id是:{{talent.id}}
还可以使用 UppercasePipe 进行格式化
使用 UppercasePipe 进行格式化:{{ talent.name | uppercase }}
5、编辑人才名字,使用双向数据绑定
想让这种数据流动自动化,就要在表单元素 和组件的 talent.name 属性之间建立双向数据绑定
首先现在app.module.ts导入FormsModule
app.module.ts
import { FormsModule } from '@angular/forms';
imports: [
BrowserModule,
FormsModule
],
修改人才列表src/app/components/talents/talents.component.html
三、显示人才列表
1、用mock创建模拟人才数据
ng g class mock-talents
导入人才talent,修改模拟数据mock-talents.ts代码,修改代码如下
import { Talent } from './talent';
export const TALENT:Talent[]=[
{ id: 1, name: 'Mr. 1' },
{ id: 2, name: 'Mr. 2' },
{ id: 3, name: 'Mr. 3' },
{ id: 4, name: 'Mr. 4' },
{ id: 5, name: 'Mr. 5' },
{ id: 6, name: 'Mr. 6' },
{ id: 7, name: 'Mr. 7' },
{ id: 8, name: 'Mr. 8' },
{ id: 9, name: 'Mr. 9' },
{ id: 10, name: 'Mr. 10' }
];
2、显示模拟人才数据
在人才列表TalentsComponent类文件,并且导入模拟数据TALENTS
src/app/components/talents/talents.component.ts
import { Component, OnInit } from '@angular/core';
import { Talent } from '../../talent';
import { TALENTS } from '../../mock-talents';//导入模拟数据
@Component({
selector: 'app-talents',
templateUrl: './talents.component.html',
styleUrls: ['./talents.component.css']
})
export class TalentsComponent implements OnInit {
// talent='Mr.1'
talent:Talent={
id: 1,
name: 'Mr.1'
};
talents=TALENTS;//往类中添加一个 talents 属性,这样可以暴露出这些人才,以供绑定
constructor() { }
ngOnInit() {
}
}
在视图显示模拟数据
src/app/components/talents/talents.component.html
显示模拟数据
- id是{{talent.id}}姓名是{{talent.name}}
给模拟数据添加样式
src/app/components/talents/talents.component.css
.selected {
background-color: #CFD8DC !important;
color: white;
}
.talents {
margin: 0 0 2em 0;
list-style-type: none;
padding: 0;
width: 15em;
}
.talents li {
cursor: pointer;
position: relative;
left: 0;
background-color: #EEE;
margin: .5em;
padding: .3em 0;
height: 1.6em;
border-radius: 4px;
}
.talents li.selected:hover {
background-color: #BBD8DC !important;
color: white;
}
.talents li:hover {
color: #607D8B;
background-color: #DDD;
left: .1em;
}
.talents .text {
position: relative;
top: -3px;
}
.talents .badge {
display: inline-block;
font-size: small;
color: white;
padding: 0.8em 0.7em 0 0.7em;
background-color: #607D8B;
line-height: 1em;
position: relative;
left: -1px;
top: -4px;
height: 1.8em;
margin-right: .8em;
border-radius: 4px 0 0 4px;
}
3、给模拟数据绑定事件
给每个人才添加绑定事件 (click)="onSelect(talent)"
src/app/components/talents/talents.component.html
- id是{{talent.id}}姓名是{{talent.name}}
添加点击事件方法
src/app/components/talents/talents.component.ts
selectedTalent:Talent;
// 事件绑定
onSelect(talent:Talent):void{
this.selectedTalent=talent;//把模板中被点击的人才赋值给组件的 selectedTalent属性
}
import { Component, OnInit } from '@angular/core';
import { Talent } from '../../talent';
import { TALENTS } from '../../mock-talents';//导入模拟数据
@Component({
selector: 'app-talents',
templateUrl: './talents.component.html',
styleUrls: ['./talents.component.css']
})
export class TalentsComponent implements OnInit {
// talent='Mr.1'
talent:Talent={
id: 1,
name: 'Mr.1'
};
talents=TALENTS;//往类中添加一个 talents 属性,这样可以暴露出这些人才,以供绑定
selectedTalent:Talent;//把该组件的 Talent 属性改名为 selectedTalent, 因为应用刚刚启动时并没有所选的人才
constructor() { }
ngOnInit() {
}
// 事件绑定
onSelect(talent:Talent):void{
this.selectedTalent=talent;//把模板中被点击的人才赋值给组件的 selectedTalent属性
}
}
4、修改详情模版
要添加*ngIf="selectedTalent",因为还没有选择人才,但绑定表达式引用了selectedTalent属性
src/app/components/talents/talents.component.html
显示模拟数据
- id是{{talent.id}}姓名是{{talent.name}}
修改详情模版
id是:{{selectedTalent.id}}
{{ selectedTalent.name | uppercase }}
5、给所选中的人才添加样式
src/app/components/talents/talents.component.html
显示模拟数据
四、父子组件
1、分离人才列表和选中的人才详情,创建应该新的人才详情组件
ng g component components/talent-detail
把人才列表talents.component.html的列表详情复制过来
src/app/components/talent-detail/talent-detail.component.html
详情模版
id是:{{selectedTalent.id}}
{{ selectedTalent.name | uppercase }}
并且把selectedTalent修改为@Input() talent:Talent;(talent),修改代码如下
详情模版
id是:{{talent.id}}
{{ talent.name | uppercase }}
2、子组件接受父组件,并导入人才Talent,添加@Input装饰器
src/app/components/talent-detail/talent-detail.component.ts
import { Component, OnInit,Input} from '@angular/core';
import { Talent } from '../../talent';
@Component({
selector: 'app-talent-detail',
templateUrl: './talent-detail.component.html',
styleUrls: ['./talent-detail.component.css']
})
export class TalentDetailComponent implements OnInit {
@Input() talent:Talent;//接收从父组件的值
constructor() {}
ngOnInit() {
}
}
3、父组件使用子组件app-talent-detail
五、Angular中的服务
1、创建服务用于访问数据
ng g service services/talent
angular很多用到箭头函数,请参考箭头函数https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions
2、同步获取数据(不能用于远端服务数据请求)
导入Talent和TALENTS
src/app/services/talent.service.ts
import { Injectable } from '@angular/core';
import { Talent } from '../talent';
import { TALENTS } from '../mock-talents';//导入模拟数据
//从远端服务获取数据,需要异步操作去处理
// Angular HttpClient 的方法会返回 RxJS 的 Observable
//使用Observable异步函数签名
import { Observable, of } from 'rxjs';
//@Injectable() 装饰器
@Injectable({
//为该服务把提供商注册到根注入器上
// providedIn 元数据的值是 'root'
providedIn: 'root'
})
export class TalentService {
constructor() { }
// 同步获取数据
getTalents(): Talent[]{//把模拟数据返回
return TALENTS;
}
}
人才列表修改,删除导入模拟数据TALENTS,导入TalentService
src/app/components/talents/talents.component.ts
import { Component, OnInit } from '@angular/core';
import { Talent } from '../../talent';
// import { TALENTS } from '../../mock-talents';//导入模拟数据
// 删除导入模拟数据
import { TalentService } from '../../services/talent.service';
@Component({
selector: 'app-talents',
templateUrl: './talents.component.html',
styleUrls: ['./talents.component.css']
})
export class TalentsComponent implements OnInit {
// talents=TALENTS;//往类中添加一个 talents 属性,这样可以暴露出这些人才,以供绑定
selectedTalent:Talent;//把该组件的 Talent 属性改名为 selectedTalent, 因为应用刚刚启动时并没有所选的人才
talents:Talent[];
constructor(private talentService:TalentService) { }
ngOnInit() {
this.getTalents();// ngOnInit 生命周期钩子中调用 getHeroes()
}
// 事件绑定
onSelect(talent:Talent):void{
this.selectedTalent=talent;//把模板中被点击的人才赋值给组件的 selectedTalent属性
}
getTalents():void{
// this.talentService.getTalents().subscribe(talents=>this.talents=talents);
//talentService.getTalents();是函数签名是同步
//从远端服务获取数据,需要异步操作去处理
//talentService.getTalents()需要有异步函数签名
//可以使用回调函数,可以返回 Promise(承诺),也可以返回 Observable(可观察对象)
//使用HttpClient.get()方法来获取数据,而HttpClient.get()会返回Observable
//Observable是RXJS库中的关键类
// Angular HttpClient 的方法会返回 RxJS 的 Observable和 of符号
// 同步获取数据
this.talents=this.talentService.getTalents();//getTalents返回TALENTS模拟数据
}
}
3、异步获取数据,使用Observable
导入Talent和TALENTS
src/app/services/talent.service.ts
import { Component, OnInit } from '@angular/core';
import { Talent } from '../../talent';
// import { TALENTS } from '../../mock-talents';//导入模拟数据
// 删除导入模拟数据
import { TalentService } from '../../services/talent.service';
@Component({
selector: 'app-talents',
templateUrl: './talents.component.html',
styleUrls: ['./talents.component.css']
})
export class TalentsComponent implements OnInit {
// talents=TALENTS;//往类中添加一个 talents 属性,这样可以暴露出这些人才,以供绑定
selectedTalent:Talent;//把该组件的 Talent 属性改名为 selectedTalent, 因为应用刚刚启动时并没有所选的人才
talents:Talent[];
constructor(private talentService:TalentService) { }
ngOnInit() {
this.getTalents();// ngOnInit 生命周期钩子中调用 getHeroes()
}
// 事件绑定
onSelect(talent:Talent):void{
this.selectedTalent=talent;//把模板中被点击的人才赋值给组件的 selectedTalent属性
}
getTalents():void{
// this.talentService.getTalents().subscribe(talents=>this.talents=talents);
//talentService.getTalents();是函数签名是同步
//从远端服务获取数据,需要异步操作去处理
//talentService.getTalents()需要有异步函数签名
//可以使用回调函数,可以返回 Promise(承诺),也可以返回 Observable(可观察对象)
//使用HttpClient.get()方法来获取数据,而HttpClient.get()会返回Observable
//Observable是RXJS库中的关键类
// Angular HttpClient 的方法会返回 RxJS 的 Observable和 of符号
// 同步获取数据
// this.talents=this.talentService.getTalents();//getTalents返回TALENTS模拟数据
// 用Observable和异步函数签名异步获取数据
//subscribe订阅获取的数据
this.talentService.getTalents().subscribe(talents=>this.talents=talents);
//Observable.subscribe() 是关键的差异点
}
}
4、显示消息
创建显示消息
ng g component messages