ng-做一個簡單的通訊錄--學習使用路由和HTTP

来源:https://www.cnblogs.com/ygjzs/archive/2020/01/22/12228490.html
-Advertisement-
Play Games

app.module 路由模塊 路由守衛 統一處理認證 註冊 登錄 頁面刪除功能 typescript import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router' import ...


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)
      })
  }

}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 要點 導出特性 如何導出Excel表頭 如何導出數據、如何進行數據的切割、如何使用篩選器 導出特性 ExporterAttribute + Name : 名稱(當前Sheet 名稱) + HeaderFontSize :頭部字體大小 + FontSize :正文字體大小 + MaxRowNumber ...
  • 首先在左下角輸入cmd搜索->命令提示符->以管理員身份運行->然後複製下麵一段命令: dism /online /norestart /add-package:%SystemRoot%\servicing\Packages\Microsoft-Windows-IIS-WebServer-AddOn ...
  • https://sqlserver.code.blog/2020/01/22/failed-to-restart-polybase-data-movement-after-running-sp_polybase_join_group/ ...
  • 函數 與其他大多數電腦語言一樣,SQL支持利用函數來處理數據。函數 一般是在數據上執行的,它給數據的轉換和處理提供了方便。 在前一章中用來去掉串尾空格的 RTrim() 就是一個函數的例子 函數沒有SQL的可移植性強 能運行在多個系統上的代碼稱 為可移植的(portable)。相對來說,多數SQL ...
  • 計算欄位 存儲在資料庫表中的數據一般不是應用程式所需要的格式。下麵舉 幾個例子。 * 如果想在一個欄位中既顯示公司名,又顯示公司的地址,但這兩 個信息一般包含在不同的表列中。 * 城市、州和郵政編碼存儲在不同的列中(應該這樣),但郵件標簽 列印程式卻需要把它們作為一個恰當格式的欄位檢索出來。 * 列 ...
  • 1.首先我們可以用管理員用戶以sysdba的身份登錄oracle sqlplus username/password as sysdba 2.然後我就可以來創建用戶了. create user username identified by password; 3.創建好用戶我們接著就可以修改用戶的密 ...
  • Ecmascript 6 ECMAScript 6.0(以下簡稱ES6)是JavaScript語言的下一代標準,已經在2015年6月正式發佈了。 Ecmascript 是 JavaScript 語言的標註規範 JavaScript 是 Ecmascript 規範的具體實現 + 具體實現取決於各大瀏覽 ...
  • 我的項目由客戶端、後臺管理、資料庫和伺服器三部分組件,每次啟動項目都要一個一個啟動,挺麻煩的,現在寫一個.bat文件來批處理命令。 這個是我的啟動文件內容。 第一行運行的我wampServer伺服器,我用這個來運行和管理mySql 第二行,先啟動一個新的命令行視窗,\K 是為了不讓視窗自動關閉,我需 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...