Angular做一個筆記文章管理應用

Mr_weiwei_發表於2019-03-04

前言

相信大家在逛技術論壇或者技術部落格的時候,都會發現有些寫的很好的文章我們想儲存下來以便可以重複翻閱和檢視,在一些相對大的站點,比如掘金或者SegmentFault都會提供類似收藏這樣的功能來幫我們做這個儲存的工作,我們以後可以回來重複檢視,但是我們平時瀏覽的站點肯定不止一個,並且有時候一些個人的技術部落格並沒有這樣的功能,我們就只能存瀏覽器書籤這樣做了,這樣我們平時儲存下來的一些文章就會比較分散,沒有一個統一的地方來幫我們管理,如果有這樣一個應用,我們只要輸入某篇我們想儲存的文章的URL地址就可以幫我們生成這篇文章的正文內容,並且可以支援標籤的分類和搜尋等功能就好了,就是基於這個需求和我平時個人的使用經驗開發出了這個應用。大家可以進這個地址先體驗一下,賬號是test,密碼123456。該應用採用Angular4開發,koa2提供資料介面,因為我是Angular的初學者,邊看官方文件邊把這個應用做了出來的,也遇到了一些問題,下面我大概說一下開發的過程和遇到的一些問題的解決方案。技術方案選型如下

  • Angular 前端框架
  • Angular Cli 前端打包構建
  • koa2 提供資料介面
  • MongoDB 提供資料儲存
  • phantom 和 node-readability 提供對文章正文的提取

一、專案的初始化

Angular是一個正式釋出於16年九月的一個前端框架(其實Angular的定位是一個平臺了),它和vue、react不太一樣的是,Angular不只是針對檢視層的一個庫,它提供的是一個完整的解決方案和生態,它本身內建了元件化方案、模組化方案、測試、表單驗證、路由、國際化和HTTP服務等,這些東西我們開發者不用再去糾結怎麼選擇,直接按官方的建議說明走就好了,選擇困難症患者肯定很喜歡這樣的,但相對的它也就沒有vue和react那麼靈活了,這個怎麼看待得根據我們每個人的專案需求來選擇。既然Angular它本身是這麼完整的了,它肯定也有CLI工具,那就是Angular CLI,Angular CLI是一個命令列介面工具,它可以建立專案、新增檔案以及執行一大堆開發任務,比如測試、打包和釋出。我們可以先執行以下命令全域性安裝Angular CLI

npm install -g @angular/cli

然後執行ng new [ProjectName]就可以初始化一個專案了。

二、模組化與元件化

Angular 應用是模組化的,並且 Angular 有自己的模組系統,它被稱為NgModules。我們的應用由一個或者多個模組組成,並且必須要有一個根模組,我們通常命名為AppModule,每個模組都會有一個叫@NgModule的裝飾器函式,它接收一個用來描述模組屬性的後設資料物件,我們在這個物件屬性上配置我們應用所需的元件、路由、指令、管道、服務等。然後Angular會引導根模組來啟動應用,有如下程式碼

import { platformBrowserDynamic } from `@angular/platform-browser-dynamic`;
import { AppModule } from `./app/app.module`;

platformBrowserDynamic().bootstrapModule(AppModule);複製程式碼

Angular應用還是元件化的,元件負責控制螢幕上的一小塊區域,稱之為檢視,每個元件也有一個叫@Component的裝飾器函式,它也接收一個後設資料物件,我們可以在該物件屬性上配置元件的模板檔案,和元件模板的樣式檔案等,看如下程式碼

@Component({
  selector: `app-root`,
  templateUrl: `./app.component.html`,
  styleUrls: [`./app.component.scss`]
})複製程式碼

這樣我們就可以組合不同的元件拼裝起我們整個應用了。整體架構圖如下

三、路由配置

Angular的路由是通過一個叫RouterModule的模組來配置的,RouterModule在@angular/router這個包裡面,所以路由配置模組RouterModule需要先從@angular/router這個包匯出來,然後呼叫RouterModule的forRoot方法給他傳進去一個陣列配置物件就好了,需要注意的是我們還要有一個路由來匹配我們所有路由都不配置的情況,它的path應該寫成兩個星號 **

import { Routes, RouterModule } from `@angular/router`;
const routes: Routes = [
  {
    path: `index`,
    component: IndexComponent
  },
  {
    path: `**`,
    redirectTo: `index`,
    pathMatch: `full`
  }
])
@NgModule({
  imports: [RouterModule.forRoot(routes)]
    ...
})複製程式碼

路由配置好後把它的返回值新增到AppModule的imports陣列裡面就好了。然後在我們的根元件appComponent的模板裡面新增<router-outlet></router-outlet>來作為我們的路由渲染出口,到這裡基本路由配置就完成了。當然Angular路由的內容還有很多,比如路由守衛,路由模組的劃分,路由的傳值等等,更加詳細的內容可以檢視Angular的中文文件

四、目錄結構劃分

目錄的劃分我是根據個人的開發習慣來做的,我們的業務邏輯的開發大多在app資料夾下進行,我一般會在app資料夾下新建一個pages檔案來做頁面級別元件的存放,然後會分別新建directive、pip、service、animation、interceptor資料夾來存放我們應用的指令、管道、服務、動畫、攔截器,因為這個應用我沒有用一些第三方的UI元件庫,一些通用的元件都是自己封裝的,所以還需要一個component資料夾來存放整個應用所需的一些通用UI元件,這樣我們整個應用的劃分就很清晰了。最後的目錄說明大致如下


app
├── animations   // 動畫
│   └── global-router-animation.ts
├── app-routing.module.ts   // 路由的配置檔案
├── app.component.html  // 根元件的模板檔案
├── app.component.scss // 根元件的樣式檔案
├── app.component.spec.ts // 根元件的測試檔案
├── app.component.ts  // 根元件
├── app.module.ts  // 根模組
├── component    // 通用的UI元件
├── button
│   └── dropdown
├── directives   // 指令
│   └── markdown-editor
├── interceptor  // 攔截器
│   └── global-response-interceptor.ts
├── page  // 頁面級別的元件
│   ├── add-link-note
│   ├── add-note
│   ├── classification
│   ├── edit-note
│   ├── index
│   ├── search
│   ├── tag
│   └── view-note
└─ services  // 服務
    ├── loading-bar
    ├── msg
    ├── note
    └── tag複製程式碼

五、跨域問題

跨域問題幾乎是現代前端專案都會遇到的了,在vue,react等專案專案中我們可以通過webpack-dev-server的代理配置來解決,Angular CLI建立出來的專案底層也是通過webpack來進行應用的打包編譯的,但是Angular CLI把webpack的配置給包裝隱藏起來了,我們可以通過執行命令ng eject來暴露出webpack的配置檔案,但就為了配置跨域問題就把webpack的配置暴露出來其實沒有必要。我們可以這樣做,先在專案的根目錄地下新建一個proxy.config.json配置檔案,在該檔案裡面寫下如下程式碼,告訴Angular,應用裡面所有以api開頭的HTTP請求都轉發到localhost的3002埠。

{
  "/api":{
    "target":"http://localhost:3002"
  }
}複製程式碼

寫完該配置檔案後我們還需要在package.json的start命令裡面加上這個配置

"start" : "ng serve --proxy-config proxy.config.json"複製程式碼

然後執行npm run start重啟服務,這樣我們的跨域問題就很簡單的解決了。

六、未解決的問題

前面有說過這個應用沒有使用一些第三方的UI元件庫,專案中用到的一些UI元件是我自己封裝的,其中有一個LoadingBar元件和message訊息提示元件,它的呼叫方式應該是通過服務的形式來呼叫的,類似如下程式碼

this.loadingBar.start()
this.msg.info(`這是訊息提示`)複製程式碼

但是在Angular裡面服務本身是不帶模板的,只有元件才有模板,所以這樣的元件應該是要通過服務去動態的載入一個帶模板的元件,但是我沒有找到相關的實現方案,去看了一下ng-zorro的原始碼沒看懂?,這裡希望有大神賜教。最後我的實現是通過最不優雅的一種方案,直接在服務裡面是操作DOM了。比如我的LoadingBar服務

import { Injectable } from `@angular/core`;

@Injectable()
export class LoadingBarService {
  constructor() { }

  public $Loading = {
    start: function(){
      const myLoadingBar = document.querySelector(`.my-loading-bar`);
      if (myLoadingBar !== null && myLoadingBar instanceof HTMLElement) {
        let LoadingBarDivWidth = 0;
        this.timer = setInterval(() => {
          LoadingBarDivWidth++;
          myLoadingBar.style.width = LoadingBarDivWidth + `vw`;
          if (LoadingBarDivWidth >= 100) {
            clearInterval(this.timer);
          }
        }, 25);
      } else {
        const LoadingBarDiv = document.createElement(`div`);
        LoadingBarDiv.className = `my-loading-bar`;
        const bodyEl = document.querySelector(`body`);
        bodyEl.appendChild(LoadingBarDiv);
        let LoadingBarDivWidth = 0;
        this.timer = setInterval(() => {
          LoadingBarDivWidth++;
          LoadingBarDiv.style.width = LoadingBarDivWidth + `vw`;
          if (LoadingBarDivWidth >= 100) {
            clearInterval(this.timer);
          }
        }, 25);
      }
    },
    finish: function(){
      const myLoadingBar = document.querySelector(`.my-loading-bar`);
      if (myLoadingBar !== null && myLoadingBar instanceof HTMLElement) {
        clearInterval(this.timer);
        myLoadingBar.style.width = 0 + `vw`;
      }
    }
  };
}複製程式碼

七、打包

在我們整個應用開發完成後我們需要build出靜態檔案交由node來部署,這裡有幾個需要注意一下。在CLI生成的專案的編譯配置命令裡面是沒有開啟加–prod配置的,需要我們手動去加上命令開啟,加上--prod之後打包出來的資源就不會再有resource map了,這樣檔案體積會小很多,如果Angular Cli用的是1.3.0以上的版本還可以加上--build-optimizer(搖樹優化),檔案體積會更加小,在我做這個專案時用的版本還是1.2.7。最後build的命令配置如下

"build" : "ng build --prod --build-optimizer"複製程式碼

八、總結

本文只是一個Angular新手做的第一個專案的流水總結,並沒有說到什麼新意有深度的東西。Angular是一個很好的框架,上手門檻沒有大多數人想象的那麼高,只要你JavaScript基礎紮實,對ES6的語法有基本的瞭解就可以去學習,相信會給到你不一樣的開發體驗。最後奉上專案的基本資訊

其實該應用如果大家有自己的個人伺服器的話完全可以部署給自己使用,如果沒有也可以部署到國外的一些免費服務提供商比如heroku上。好啦,如果大家對該專案有什麼問題和建議歡迎留言一起討論。

相關文章