app.module

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {FormsModule} from '@angular/forms';
import {HttpClientModule} from '@angular/common/http';
import {HTTP_INTERCEPTORS} from '@angular/common/http' import {GlobalInterceptor} from './global.interceptor' // 开启 HTTP 功能
// open the root AppModule,
// import the HttpClientModule symbol from @angular/common/http,
// add it to the @NgModule.imports array. import { AppComponent } from './app.component';
import { NavbarComponent } from './navbar/navbar.component';
import { SidebarComponent } from './sidebar/sidebar.component';
import { SigninComponent } from './signin/signin.component';
import { SignupComponent } from './signup/signup.component';
import { ContactListComponent } from './contact-list/contact-list.component';
import { ContactNewComponent } from './contact-new/contact-new.component';
import { ContactEditComponent } from './contact-edit/contact-edit.component';
import { TagListComponent } from './tag-list/tag-list.component';
import { TagNewComponent } from './tag-new/tag-new.component';
import { TagEditComponent } from './tag-edit/tag-edit.component';
import { AppRoutingModule } from './/app-routing.module';
import { LayoutComponent } from './layout/layout.component'; @NgModule({
declarations: [
AppComponent,
NavbarComponent,
SidebarComponent,
SigninComponent,
SignupComponent,
ContactListComponent,
ContactNewComponent,
ContactEditComponent,
TagListComponent,
TagNewComponent,
TagEditComponent,
LayoutComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
HttpClientModule
],
providers: [{
provide: HTTP_INTERCEPTORS,
useClass: GlobalInterceptor,
multi: true
}],
bootstrap: [AppComponent]
})
export class AppModule { }

路由模块



// 0. 路由模块初始化
// 1. 配置路由表
// 请求 xxx 路径的时候,导航到 xxx 组件
// 2. 配置路由出口及路由导航链接
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import {AuthGuard} from './auth-guard.service' import {LayoutComponent} from './layout/layout.component' import {ContactListComponent} from './contact-list/contact-list.component'
import {ContactNewComponent} from './contact-new/contact-new.component'
import {ContactEditComponent} from './contact-edit/contact-edit.component' import {TagListComponent} from './tag-list/tag-list.component'
import {TagNewComponent} from './tag-new/tag-new.component'
import {TagEditComponent} from './tag-edit/tag-edit.component' import {SigninComponent} from './signin/signin.component'
import {SignupComponent} from './signup/signup.component' const routes: Routes = [
{
path: '',
redirectTo: '/contacts', // 当请求根路径的时候,跳转到 contacts 联系人组件
pathMatch: 'full' // 必须完全匹配到路径的时候才做重定向
},
{
// 当我们访问 contacts 的时候,会先把 LayoutComponent 组件渲染出来
// 然后把 children 中 path 为空的路由渲染到 LayoutComponent 组件中的路由出口
path: 'contacts',
component: LayoutComponent,
canActivate: [AuthGuard], // 在导航 contacts 之前会先进入路由守卫
children: [
{
path: '',
component: ContactListComponent
},
{
path: 'new', // 这里的 new 的请求路径是 /contacts/new
component: ContactNewComponent
},
{
path: 'edit/:id', // 动态路径
component: ContactEditComponent
}
]
},
{
// 当我们访问 contacts 的时候,会先把 LayoutComponent 组件渲染出来
// 然后把 children 中 path 为空的路由渲染到 LayoutComponent 组件中的路由出口
path: 'tags',
component: LayoutComponent,
canActivate: [AuthGuard],
children: [
{
path: '',
component: TagListComponent
},
{
path: 'new', // 这里的 new 的请求路径是 /contacts/new
component: TagNewComponent
},
{
path: 'edit',
component: TagEditComponent
}
]
},
{
path: 'signin',
component: SigninComponent
},
{
path: 'signup',
component: SignupComponent
}
] @NgModule({
imports: [
RouterModule.forRoot(routes)
],
exports: [ RouterModule ],
providers: [AuthGuard]
})
export class AppRoutingModule {}

路由守卫

import { Injectable }     from '@angular/core';
import { CanActivate, Router } from '@angular/router'; @Injectable()
export class AuthGuard implements CanActivate {
constructor (
private router: Router
) {}
canActivate() {
const token = window.localStorage.getItem('auth_token')
if (!token) {
this.router.navigate(['/signin'])
return false // 不能继续导航
} // 如果验证通过,则放行,继续完成导航
return true;
}
}

统一处理认证

import {Injectable} from '@angular/core';
import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest} from '@angular/common/http'; import {Observable} from 'rxjs/Observable'; @Injectable()
export class GlobalInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const token = window.localStorage.getItem('auth_token')
const authReq = req.clone({headers: req.headers.set('X-Access-Token', token)});
return next.handle(authReq);
}
}

注册

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http'
import { Router } from '@angular/router' @Component({
selector: 'app-signup',
templateUrl: './signup.component.html',
styleUrls: ['./signup.component.css']
})
export class SignupComponent implements OnInit { signupForm = {
email: '',
password: ''
} email_err_msg = '' // 在组件类中声明了一个私有成员 http 它的类型是 HttpClient
// 那么 Angular 会自动去实例化 HttpClient 得到一个实例
// 然后我们就可以在组件中使用 http 这个成员来调用一些请求方法了
// 例如 http.get http.post...
constructor(
private http: HttpClient,
private router: Router
) { } ngOnInit() {
} signup() {
// 1. 表单验证
// 2. 获取表单数据
// 3. 发起 http 请求和服务端交互
// 4. 根据响应结果做交互处理
const formData = this.signupForm
this.http.post('http://localhost:3000/users', formData)
.toPromise()
.then((data: any) => {
this.email_err_msg = ''
window.localStorage.setItem('auth_token', data.token)
window.localStorage.setItem('user_info', JSON.stringify(data.user))
this.router.navigate(['/'])
})
.catch(err => {
if (err.status === 409) {
this.email_err_msg = '邮箱已被占用'
}
})
} }

登录

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http'
import { Router } from '@angular/router' @Component({
selector: 'app-signin',
templateUrl: './signin.component.html',
styleUrls: ['./signin.component.css']
})
export class SigninComponent implements OnInit {
signinForm = {
email: '',
password: ''
} err_message = '' constructor(
private http: HttpClient,
private router: Router
) { } ngOnInit() {
} signin () {
this.http.post('http://localhost:3000/session', this.signinForm)
.toPromise()
.then((data: any) => {
window.localStorage.setItem('auth_token', data.token)
window.localStorage.setItem('user_info', JSON.stringify(data.user))
this.router.navigate(['/'])
})
.catch(err => {
if (err.status === 401) {
this.err_message = '登陆失败,邮箱或密码错误'
}
})
}
}

页面删除功能

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router'
import { HttpClient, HttpHeaders } from '@angular/common/http' @Component({
selector: 'app-contact-list',
templateUrl: './contact-list.component.html',
styleUrls: ['./contact-list.component.css']
})
export class ContactListComponent implements OnInit { public contacts: any constructor(
private router: Router,
private http: HttpClient
) { } ngOnInit() {
this.getContacts()
} getContacts() {
this.http.get('http://localhost:3000/contacts')
.toPromise()
.then(data => {
this.contacts = data
console.log(this.contacts)
})
.catch(err => {
console.log(err)
})
} deleteContactById(id, e) {
e.preventDefault()
if (!window.confirm('确定删除吗?')) {
return
}
this.http.delete(`http://localhost:3000/contacts/${id}`)
.toPromise()
.then(data => {
this.getContacts()
})
.catch(err => {
console.log(err)
})
} }

编辑

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router'
import { HttpClient } from '@angular/common/http' @Component({
selector: 'app-contact-edit',
templateUrl: './contact-edit.component.html',
styleUrls: ['./contact-edit.component.css']
})
export class ContactEditComponent implements OnInit {
formData = {
name: '',
email: '',
phone: '',
id: 0
}; constructor(
private router: Router,
private route: ActivatedRoute,
private http: HttpClient
) { } ngOnInit() {
// 如何在组件中获取路由动态路径参数
const contactId = this.route.snapshot.params.id
this.getContactById(contactId)
} getContactById (id) {
this.http.get(`http://localhost:3000/contacts/${id}`)
.toPromise()
.then((data: any) => {
this.formData = data
})
.catch(err => {
console.log(err)
})
} editContact () {
const id = this.formData.id
this.http.patch(`http://localhost:3000/contacts/${id}`, this.formData)
.toPromise()
.then(data => {
this.router.navigate(['/contacts'])
})
.catch(err => {
console.log(err)
})
} }

ng-做一个简单的通讯录--学习使用路由和HTTP的更多相关文章

  1. QML学习笔记(五)— 做一个简单的待做事项列表

    做一个简单的QML待做事项列表,能够动态添加和删除和编辑数据 GitHub:八至 作者:狐狸家的鱼 本文链接:QML学习笔记(五)— 做一个待做事项列表 主要用到QML:ListView 效果 全部代 ...

  2. 使用React并做一个简单的to-do-list

    1. 前言 说到React,我从一年之前就开始试着了解并且看了相关的入门教程,而且还买过一本<React:引领未来的用户界面开发框架 >拜读.React的轻量组件化的思想及其virtual ...

  3. 【 D3.js 入门系列 --- 3 】 做一个简单的图表!

    前面说了几节,都是对文字进行处理,这一节中将用 D3.js 做一个简单的柱形图. 做柱形图有很多种方法,比如用 HTML 的 div 标签,或用 svg . 推荐用 SVG 来做各种图形.SVG 意为 ...

  4. 【 D3.js 入门系列 — 3 】 做一个简单的图表!

    图1. 柱形图 1. 柱形图 前几章的例子,都是对文字进行处理.本章中将用 D3 做一个简单的柱形图.制作柱形图有很多种方法,比如用 HTML 的 <div> 标签,或在 SVG 上绘制 ...

  5. 程序猿修仙之路--数据结构之你是否真的懂数组? c#socket TCP同步网络通信 用lambda表达式树替代反射 ASP.NET MVC如何做一个简单的非法登录拦截

    程序猿修仙之路--数据结构之你是否真的懂数组?   数据结构 但凡IT江湖侠士,算法与数据结构为必修之课.早有前辈已经明确指出:程序=算法+数据结构  .要想在之后的江湖历练中通关,数据结构必不可少. ...

  6. 【Bugly干货分享】一起用 HTML5 Canvas 做一个简单又骚气的粒子引擎

    Bugly 技术干货系列内容主要涉及移动开发方向,是由Bugly邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟撰写而成,内容均属原创,转载请标明出处. 前言 好吧,说是“粒子引擎”还是大言不 ...

  7. 一起用HTML5 canvas做一个简单又骚气的粒子引擎

    前言 好吧,说是"粒子引擎"还是大言不惭而标题党了,离真正的粒子引擎还有点远.废话少说,先看demo 本文将教会你做一个简单的canvas粒子制造器(下称引擎). 世界观 这个简单 ...

  8. Jmeter初步使用二--使用jmeter做一个简单的性能测试

    经过上一次的初步使用,我们懂得了Jmeter的安装与初步使用的方法.现在,我们使用Jmeter做一个简单的性能测试.该次测试,提交的参数不做参数化处理,Jmeter各元件使用将在介绍在下一博文开始介绍 ...

  9. 用EF DataBase First做一个简单的MVC3报名页面

    使用EF DataBase First做一个简单的MVC3报名网站 ORM(Object Relational Mapping)是面向对象语言中的一种数据访问技术,在ASP.NET中,可以通过ADO. ...

随机推荐

  1. for和while——python中的循环控制语句详解

    循环语句在绝大多数的语言中,都是必不可少的一种控制语句,循环语句允许我们执行一个语句或语句组多次.在python中有for循环和while循环两种,讲到这里,就不得不提到我们的迭代器对象 迭代器 迭代 ...

  2. asp.net core系列 WebAPI 作者:懒懒的程序员一枚

    asp.net core系列 36 WebAPI 搭建详细示例一.概述1.1 创建web项目1.2 添加模型类1.3 添加数据库上下文1.4 注册上下文1.5 添加控制器1.6 添加Get方法1.7 ...

  3. Go语言实现:【剑指offer】把字符串转换成整数

    该题目来源于牛客网<剑指offer>专题. 将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数. 输入描述: 输入一个字符串,包括数字字母符号,可以为空. 输出描述: 如果是合 ...

  4. GitHub新手教学(从新手安装到初步使用)

    版权声明:本文为博主原创文章,转载请标明出处! 博客地址:http://blog.csdn.net/qazwsxpcm https://blog.csdn.net/qazwsxpcm/article/ ...

  5. [redis读书笔记] 第二部分 单机数据库 数据库实现

    一 数据库基本实现/命令下发的实现 redis.c里,大家能看到redisCommandTable[] 的实现,列出了支持的所有命令.大部分的入参为redisClient *c,当一条REDIS命令下 ...

  6. 【大白话系统】MySQL 学习总结 之 缓冲池(Buffer Pool) 如何支撑高并发和动态调整

    如果大家对我的 [大白话系列]MySQL 学习总结系列 感兴趣的话,可以点击关注一波. 一.上节回顾 在上节< 缓冲池(Buffer Pool) 的设计原理和管理机制>中,介绍了缓冲池整体 ...

  7. Idea自定义代码块【学习笔记】

    前言 idea有一个自定义代码块的功能,可以自定义代码块,方便以后工作中减少一些重复操作,这里就简单记录一下idea好用的模板吧,现在有一个关于日志的模板,用于写一个ServiceImpl方法的时候, ...

  8. Matplotlib数据可视化从入门到精通(持续更新)

    目录 前言 如何添加标题-title 如何添加文字-text 如何添加注释-annotate 如何设置坐标轴名称-xlabel/ylabel 如何添加图例-legend 如何调整颜色-color 如何 ...

  9. APP图标在线生成

    在线生成安卓APP图标生成 图标在线 在线图标 安卓图标 生成图标 https://icon.wuruihong.com/ 在线png图片压缩  png压缩 https://compresspng.c ...

  10. css实现表单label文字两端对齐

    如图,在我们写页面的时候,经常遇到这种的情况,而需求是想让label文字两端对齐,我们来看看如何用css解决 /**css代码**/ ul li{ list-style: none; } .info- ...