# 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的資料。

##### tags:`angular19`,`editorJs`