原本是打算把 redoc-cli 產生出來的文件直接嵌進去的,可是這樣子在文件有變動時,就會又要再做一次產生、嵌入,這樣不太好。最好還是可以自動依據寫好的 OpenAPI specification 來自動產出,這才是比較好的作法。
第一個待解決的問題是怎麼把 OpenAPI specification JSON 放到 Angular 專案裡,並且可以讀出來使用。關於這個,我是找到 How To Read Local JSON Files In Angular 這篇文章,方法挺簡單的,就把 json 檔案丟到 src/assets 下,然後直接在程式裡用 import 。
P.S. redoc 在 1.x 時,是有支援 Angular 的,但到了 2.x ,就改用 react 了。
第一個待解決的問題是怎麼把 OpenAPI specification JSON 放到 Angular 專案裡,並且可以讀出來使用。關於這個,我是找到 How To Read Local JSON Files In Angular 這篇文章,方法挺簡單的,就把 json 檔案丟到 src/assets 下,然後直接在程式裡用 import 。
// src/app/xxx/xxx.component.ts import SampleJson from '../../assets/SampleJson.json’; // 後續程式碼就直接引用 SampleJSON 即可。但修改完,TypeScript compiler 會有錯誤訊息,這得要改 tsconfig.json 在 compilerOptions 裡加入 resolveJsonModule 跟 esModuleInterop
{ "compilerOptions": { "resolveJsonModule": true, "esModuleInterop": true } }第二個問題是,angular template 裡不能直接寫 script tag,這個可以實作 AfterViewInit ,然後用 DOMElement 來動態插入 (參考來源:https://stackoverflow.com/questions/38088996/adding-script-tags-in-angular-component-template/43559644)。細節的說明,我就直接寫在下面程式的註解裡。
import { Component, OnInit, ViewEncapsulation, ElementRef, AfterViewInit } from '@angular/core’; // (1) 剛剛前面提到的,引用 OpenAPI specification JSON import APIJson from '../../assets/api.json'; @Component({ selector: 'app-documentation', templateUrl: './documentation.component.html', styleUrls: ['./documentation.component.scss'], encapsulation: ViewEncapsulation.None }) export class DocumentationComponent implements OnInit, AfterViewInit { // (2) Component 要實作 AfterViewInit 這介面 constructor(private elementRef: ElementRef) { } // (3) 引入 ElementRef ,Angular 會幫忙作動態注入 ngAfterViewInit(): void { // (4) 這裡就是在頁面載入後要作的事情 this.insertSpec(); this.insertScript(); } insertScript(): void { // (5) 插入 script element,這裡要載入 redoc 的腳本 const redocScript = document.createElement('script'); redocScript.type = 'text/javascript'; redocScript.src = 'https://unpkg.com/redoc@next/bundles/redoc.standalone.js’; // (6) 這腳本的網址是閱讀 redoc-cli 的原始碼以後取得的。 this.elementRef.nativeElement.appendChild(redocScript); // (7) 插入另外一個 script element,這裡主要是執行 redoc,讓 redoc 能解析 json 並顯示出文件。 const initScript = document.createElement('script'); initScript.type = 'text/javascript'; initScript.textContent = ` const __redoc_state=${JSON.stringify(APIJson)}; var container = document.getElementById('redoc'); Redoc.hydrate(__redoc_state, container); `; // (8) 字串要允許多行,可以使用 backquote ` https://stackoverflow.com/questions/35225399/multiline-string this.elementRef.nativeElement.appendChild(initScript); } insertSpec(): void { // (9) 插入 element ,讓腳本知道要根據哪個 element 來作處理。 let s = document.createElement('redoc'); s.setAttribute('spec-url', 'assets/api.yml'); this.elementRef.nativeElement.appendChild(s); } ngOnInit(): void { } }至此就大功告成啦。
P.S. redoc 在 1.x 時,是有支援 Angular 的,但到了 2.x ,就改用 react 了。
沒有留言:
張貼留言