背景
最近在公司開發的一個項目需要在 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 排版的文檔來渲染美觀的圖文。