ng-做一個簡單的通訊錄--學習使用路由和HTTP
阿新 • • 發佈:2020-08-11
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)
})
}
}