iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 6
1
Modern Web

高效 Coding 術:Angular Schematics 實戰三十天系列 第 6

[高效 Coding 術:Angular Schematics 實戰三十天] Day05 - JSON Schema

昨天筆者曾提到:

_options 參數是一個物件,這個參數可以使用 JSON Schema 進行驗證,以確保它具有適當的預設值與類型。

但什麼是 JSON Schema

JSON Schema

JSON Schema 是一組用來描述另一組 JSON 數據結構的 JSON 。乍聽之下很饒舌,但我們先來看個例子:

{
  "name": "Leo",
  "gender": "male",
  "age": 18
}

假設有個 JSON 如上所示,我們可能會這樣描述它的數據結構:

  • 它是一個 object
  • 它有三個屬性,其名稱為: namegenderage
  • namegender 的值的型別為 stringage 的值的型別為 number

不過這樣不夠清楚,也無法實際套用到程式之中。那如果換成一樣用 JSON 來描述呢?

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "gender": {
      "type": "string"
    },
    "age": {
      "type": "number"
    }
  }
}

這樣是不是清楚多了?!

接下來我們就來幫昨天的 hello-world 加上 JSON Schema 以驗證使用者所輸入的參數吧!

schema.json

首先先在 ./src/hello-world 的位置下新增一個 schema.json ,檔案內容如下所示:

{
  "$schema": "http://json-schema.org/schema",
  "id": "HelloSchematics",
  "title": "Hello Schema",
  "description": "Generate a file of JavaScript",
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "description": "The name of the person",
    }
  },
  "required": [
    "name"
  ]
}

這些設定的意思是:

  • $schema - 用什麼版本的 JSON Schema 來驗證。
  • id - Schema 的唯一名稱(同一個 Collection 裡不重複即可)。
  • title - 這個 Schema 的標題。
  • description - 該 Schematic 的功能描述。
  • type - 該 Schematic 的參數類型。
  • properties - 該 Schematic 的參數有哪些屬性。
  • required - 該 Schematic 的參數必須要有哪些屬性。

接著到 /src/collection.json 裡加上 schema 的設定:

{
  "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
  "schematics": {
    "hello-world": {
      "description": "A blank schematic.",
      "factory": "./hello-world/index#helloWorld",

      "//": "加入下面這行",
      "schema": "./hello-world/schema.json"
    }
  }
}

然後我們再輸入以下指令:

schematics .:hello-world

猜猜看會發生什麼事?!

Imgur

沒錯,會 Error 。

有注意到嗎?其實是因為筆者在指令中故意不加任何參數,再加上剛剛我們新增的 schema.json 裡有規範,使用時一定要有一個參數 name ,所以如果使用的時沒有給這個參數的話, Schematics CLI 執行時就會直接報錯,避免程式出錯。

既然如此,那加上參數驗證看看:

schematics .:hello-world --name=leo

結果:

Imgur

預設參數

但是每次下指令都要加參數好麻煩,筆者很懶,如果能少打幾個字就絕對不會多打。能不能像 Angular CLI 那樣,只要輸入名字就好,不要輸入參數名稱呢?

當然沒問題,我們只需要在 schema.json 加上:

{
  "//": "略",
  "properties": {
    "name": {
      "type": "string",
      "description": "The name of the person",

      "//": "加入這個設定",
      "$default": {
        "$source": "argv",
        "index": 0
      }
    }
  },
  "//": "略"
}

這個設定的意思是,下指令時的第一個參數,系統會自動把它認為是 name 這個屬性的值。

事不宜遲,輸入以下指令試試看:

schematics .:hello-world leo

結果應該要跟上一個一模一樣噢!

加入提示

一般的提示

不曉得大家記不記得,用 Angular CLI 建立新專案的時候,會出現像這樣子的提示訊息:

Imgur

這要怎麼做呢?

只要在 schema.json 加上:

{
  "//": "略",
  "properties": {
    "name": {
      "type": "string",
      "description": "The name of the person",
      "$default": {
        "$source": "argv",
        "index": 0
      },

      "//": "加入以下這行",
      "x-prompt": "What name would you like?"
    }
  },
  "//": "略"
}

再輸入以下指令:

schematics .:hello-world

結果:

Imgur

布林值的提示

有時候我們所需要的參數其型別是 boolean,所以需要在提示訊息的尾端加上 (y/n) 來提示使用者如下圖所示:

Imgur

這時候我們只需要把該參數的型別改成 boolean ,並一樣加上 x-prompt 的設定,像是:

{
  "//": "略",
  "properties": {
    "name": {
      "type": "boolean",
      "//": "略",
      "x-prompt": "What name would you like?"
    }
  },
  "//": "略"
}

結果:

Imgur

有選項的提示

在某些應用場景裡,我們希望提供一些選擇給使用者,一方面可以讓使用者知道總共有哪些選項可以選;另一方面又能避免使用者亂輸入。如下圖所示:

Imgur

這時候只要將 x-prompt 改成物件,並加上一些選項如:

{
  "//": "略",
  "properties": {
    "name": {
      "type": "string",
      "//": "略",
      "x-prompt": {
        "message": "Which name would you like?",
        "type": "list",
        "items": [
          { "value": "leo",  "label": "Leo" },
          { "value": "kevin", "label": "Kevin" },
          { "value": "mike", "label": "Mike" },
          { "value": "will", "label": "Will" },
        ]
      }
    }
  },
  "//": "略"
}

結果:

Imgur

本日結語

現今已經有非常多的應用都有使用 JSON Schema 來驗證與規範資料,希望今天筆者帶著大家玩了一輪之後,大家可以對它有著更進一步的理解。

欲看今天的程式碼請點我,筆者最後只留下最一般的提示。明天要介紹的是關於範本的應用,敬請期待。

參考資料

錯誤更新記錄

  • 2020/02/10 12:01 - 非常感謝邦友 Sonic 的提醒,更正路徑錯誤的問題。

上一篇
[高效 Coding 術:Angular Schematics 實戰三十天] Day04 - 為你的 Schematics 撰寫測試程式
下一篇
[高效 Coding 術:Angular Schematics 實戰三十天] Day06 - 與範本共舞
系列文
高效 Coding 術:Angular Schematics 實戰三十天32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
Sonic
iT邦新手 5 級 ‧ 2020-02-10 11:36:52

"首先先在 ./src/hello 的位置下新增一個 schema.json ,檔案內容如下所示:"一句

"./src/hello" 應該是 "./src/hello-world"

Leo iT邦新手 3 級 ‧ 2020-02-10 12:01:54 檢舉

Hi Sonic,

感謝提醒!錯誤已更正囉! :)

0
Charles Wang
iT邦新手 5 級 ‧ 2023-04-14 15:44:38

Angular 15
schema.json中
id要改為$id

不然會跳錯
Error: NOT SUPPORTED: keyword "id", use "$id" for schema ID

我要留言

立即登入留言