Angular 利用 marked.js 新增 Markdown + HTML 同時渲染的 Pipe
背景
最近在公司開發的一個專案需要在 Angular 上展示圖文,並且需要同時支援 Markdown 和 HTML
對於同時支援 Markdown 和 HTML ,應該要分為編輯和渲染兩部分考慮。
對於編輯,目前尚未找到同時支援兩種格式的編輯器。我個人認為 Markdown 最好的開源編輯器是 Editor.md,最好的 HTML 編輯器是 UEditor,雖然他們倆都已經很久很久沒更新過……
所以在編輯頁面就只能提供兩個編輯器的切換,對於 Markdown 和 HTML 分部用各自的編輯器。 但是,我可以存到同一個欄位嗎?
這就要考慮到渲染了,如果能找到同時支援渲染 Markdown 和 HTML 的元件,我就不需要在後端把 Markdown 原文和渲染後的 HTML 分開欄位儲存了,還有利於對 Markdown 文字的修改。
於是找到了 marked.js
marked.js 介紹
官方文件
marked.js 是一個普通的js庫,並不是 Angular 特有的元件,所以我們在整合時還是需要進行一些編碼。同時也說明它能支援其他前端框架,甚至是普通 HTML 的直接引用,非常輕量。
給 Angular 新增一個用於 Markdown 渲染的 Pipe
Angular Pipe 是 Angular 中用於字元格式轉換的元件,專門處理輸出字元的轉換,如日期、翻譯等等在Angular開發中都比較常用。今天我們就給專案新增一個用於 Markdown 渲染的 Pipe。
一、npm 引用
需要引用marked.js和它的 typescript 型別庫來輔助模組宣告
npm install marked
npm install @types/marked
二、建立 Pipe
通過 angular-cli 建立 Pipe 檔案
ng generate pipe marked
這樣它能自動建立一個名為 "marked" 的 Pipe (marked.pipe.ts
),並匯入到你的 app.module.ts
檔案中了。
修改 marked.pipe.ts
生成出來的 marked.pipe.ts
檔案如下:
import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'marked' }) export class MarkedPipe implements PipeTransform { transform(value: any, args?: any): any { return null; } }
我們需要匯入 marked , 然後修改 transform 方法來解析 Markdown 並返回 HTML 字串。
更改之後的程式碼如下:
import { Pipe, PipeTransform } from "@angular/core";
import * as marked from "marked";
@Pipe({
name: "marked"
})
export class MarkedPipe implements PipeTransform {
transform(value: any): any {
if (value && value.length > 0) {
return marked(value);
}
return value;
}
}
其中的 transform
方法將接受文字作為值,如果它有長度,則返回解析後的 HTML。否則,它只返回傳遞的值。
使用方法
使用方法跟其他 Pipe 幾乎差不多,但是有一點,就是如果渲染出來的是 HTML 字串,需要讓 Angular 自己在渲染成最終的 HTML,我們需要把 HTML 字串傳入到 Angular 模版中一個 HTML 元素的 innerHTML
屬性中,舉個例子:
// app.component.ts
...
public markdownString: string = 'This is text with **markdown**';
...
// app.component.html
...
<div [innerHTML]="markdownString | marked"></div>
...
總結
這樣就大功告成啦!你可以嘗試使用同時含有 Markdown 和 HTML 的字串,就像 Github 裡眾多開源專案的 README 文件一樣,使用穿插著 HTML 排版的文件來渲染美觀的圖文