# angular使用editorJs實現notion編輯器 在 Angular 中,使用 Editor.js 可以實現類似 Notion 的編輯體驗。Editor.js 是基於區塊 (block-based) 的 WYSIWYG 編輯器,支援可擴展的插件系統,適合結構化內容編輯,例如標題、清單、表格等。它的 JSON 輸出格式便於儲存與再利用。 相比之下,CKEditor 是傳統的 HTML 內容編輯器,適合富文本編輯 (如 Word),提供強大的樣式、表單控件、圖片上傳等功能,適用於需要完整 RTF 支援的應用。若開發 Notion 風格的編輯器,Editor.js 更靈活,但若需要 Word 類型的編輯體驗,CKEditor 更優秀。 ## 建立專案及安裝套件 1. 建立專案 安裝完後再進入專案目錄進行套件安裝 ```bash ng new ng-editer ``` 注意:==editorJs==只在瀏覽器端執行,建立專案時不能夠有==SSR==模式,否則會觸發==window is not defined==的問題 2. 安裝editorJs跟Plugin套件 Plugin套件的部份,可依各別需作選擇安裝 >參考:https://github.com/editor-js ```bash npm i @editorjs/editorjs --save npm i @editorjs/header @editorjs/simple-image @editorjs/delimiter @editorjs/list @editorjs/checklist @editorjs/quote @editorjs/code @editorjs/table @editorjs/link @editorjs/warning @editorjs/marker @editorjs/inline-code @editorjs/embed @editorjs/raw ``` ## 建立service及component service主要為引入editorJs的功能,可以視需求調整 ```typescript src\app\service\editer.service.ts import { Injectable, signal } from '@angular/core'; import EditorJS, { LogLevels } from '@editorjs/editorjs'; import Header from '@editorjs/header'; import List from '@editorjs/list'; import Delimiter from '@editorjs/delimiter'; import CodeTool from '@editorjs/code'; import Table from '@editorjs/table'; import Quote from '@editorjs/quote'; import Warning from '@editorjs/warning'; import InlineCode from '@editorjs/inline-code'; import Embed from '@editorjs/embed'; import SimpleImage from '@editorjs/simple-image'; import LinkTool from '@editorjs/link'; import RawTool from '@editorjs/raw'; @Injectable({ providedIn: 'root' }) export class EditerService { public editor!: EditorJS; public data = signal({}); constructor() { } init(Data?: any | {}) { this.editor = new EditorJS({ holder: 'editor-js', logLevel: "ERROR" as LogLevels, autofocus: true, readOnly: true, //預覽模式,無法編輯(如要編輯需設為false) tools: { header: { class: Header, inlineToolbar: ['link'], config: { placeholder: 'Header' }, shortcut: 'CMD+SHIFT+H' } as any, image: SimpleImage, linkTool: LinkTool, raw: RawTool, list: { class: List, inlineToolbar: true, shortcut: 'CMD+SHIFT+L' } as any, delimiter: Delimiter, warning: Warning, quote: { class: Quote, inlineToolbar: true, config: { quotePlaceholder: 'Enter a quote', captionPlaceholder: 'Quote\'s author', }, shortcut: 'CMD+SHIFT+O' }, code: { class: CodeTool, shortcut: 'CMD+SHIFT+C' }, table: { class: Table, inlineToolbar: true, shortcut: 'CMD+ALT+T' } as any, inlineCode: { class: InlineCode, shortcut: 'CMD+SHIFT+C' }, embed: { class: Embed, inlineToolbar: true, config: { services: { youtube: true, coub: true } } } }, onReady: () => { console.log('Editor.js is ready to work!'); }, onChange: (api, event) => { this.onDataChanges(); console.log("Now I know that Editor's content changed!", event); }, data: Data }) } private onDataChanges(): void { this.editor.save() .then(result => { this.data.set(result); console.log(result); }); } compoinent為inject剛剛所建立的Service,並且用signal偵測變更的input, 如果讀取已input的data資料,則將值帶入到defaultData } ``` ```typescript src\app\input-editer\input-editer.component.ts import { Component, inject, signal, effect } from '@angular/core'; import { EditerService } from '../service/editer.service'; import { CommonModule } from '@angular/common'; @Component({ selector: 'app-input-editer', imports: [CommonModule], templateUrl: './input-editer.component.html', styleUrl: './input-editer.component.css' }) export class InputEditerComponent { inputData = signal({}); editorService = inject(EditerService) defaultData = {}; constructor( ) { effect(() => { this.inputData.set(this.editorService.data()) }); } ngOnInit(): void { this.editorService.init(this.defaultData); } } ``` html的設定 ```htmlembedded src\app\input-editer\input-editer.component.html <div id="editor-js"></div> ``` ## Plugin設定的問題 注意:editorJs的Plugin有些使用any型態,會造成==TS7016: Could not find a declaration file for module==的問題,需要另外宣告declaration 1. 於根目錄下建立==global.d.ts==檔案,其內容如下 ```typescript global.d.ts declare module '@editorjs/embed'; declare module '@editorjs/simple-image'; declare module '@editorjs/link'; declare module '@editorjs/raw'; ``` 2. 修改==tsconfig.app.json==的設定 ```jsonld tsconfig.app.json { ...(以上省略) "include": [ "src/**/*.d.ts", "global.d.ts" //<--加入此行 ] } ``` ## 測試及預覽 完成後即可測試editorJs是否可運作,相關的套件件是否可以正常編輯及轉換,並且可以將input值帶入到defaultData,看看是否可以呈現data的資料。 ![image](https://hackmd.io/_uploads/r1JroRO61x.png) ##### tags:`angular19`,`editorJs`