【Angular4+】實現CKEditor5富文本編輯與富文本展示

Angular4+使用CKEditor5實現富文本編輯器

編輯器支持文本輸入,基本文本樣式:對齊、加粗等;粘貼上傳圖片等功能,本文圖片上傳基于自定義的上傳方法

CKEditor5提供了幾種封裝好的不同風格的富文本編輯器

實現一:使用CKEditor5-Angular2組件

CKEditor5-Angular2+官方文檔
包安裝:

npm install --save @ckeditor/ckeditor5-angular

根據需要選擇所要的editor類型,要另外安裝:

npm install --save @ckeditor/ckeditor5-build-classic

在對應的Module.ts中引入CKEditorModule

import { CKEditorModule } from '@ckeditor/ckeditor5-angular';

@NgModule( {
    imports: [
        CKEditorModule,
        // ...
    ],
    // ...
} )

實現【ckeditor/ckeditor5-build-decoupled-document】為例

config可以配置工具欄選項等等
config文檔
contentText:文本框的內容

<ckeditor 
[editor]="Editor" 
[(ngModel)]="contentText"
(ready)="onReady($event)"
[config]="config"
>
</ckeditor>
import { Component, OnInit, ViewChild, ElementRef, Output, Input, EventEmitter } from '@angular/core';
import * as DecoupledEditor from '@ckeditor/ckeditor5-build-decoupled-document';
//如果是classic-editor則替換成注釋中的語句
//import * as ClassicEditor from '@ckeditor/ckeditor5-build-classic';
import { HttpClient } from '@angular/common/http';
import { UploadAdapter } from '../service/uploadAdapter';//自定義的圖片上傳方法
 
@Component({
  selector: 'app-editor',
  templateUrl: './editor.component.html',
  styleUrls: ['./editor.component.scss']
})
export class EditorComponent implements OnInit {
  @ViewChild('toolbar') toolbar:ElementRef<any>;
  @Input() url:string='';
  @Input() config?:Object ={};//config設置配置編輯器的工具欄等屬性

  public contentText:string ='';
  public Editor = DecoupledEditor;

  constructor(
    private http:HttpClient
  ) {  }

  ngOnInit() { }
  onReady($event){
//使用decoupled-document editor需要在onReady中實現方法insertBefore
    $event.ui.getEditableElement().parentElement.insertBefore(
        $event.ui.view.toolbar.element,
        $event.ui.getEditableElement()
    );
//以下語句是配置自定義圖片上傳的UploadAdapter,如果富文本中不包含圖片可以不設置
//編輯器中的上傳圖片后,會先上傳到服務器中,除非額外實現圖片刪除方法,否則即使文本中的圖片刪除了,服務器中的文件資源依然存在
    $event.plugins.get('FileRepository').createUploadAdapter = (loader)=> {
      return new UploadAdapter(loader,this.url,this.http);
    };
  }
}

UploadAdapter:自定義圖片上傳Service

自定義圖片上傳需要后端實現圖片上傳接口
其他圖片上傳方式:CkEditor可以與CKFinder結合實現上傳圖片,但是要進行服務器端的配置,還有其他圖片上傳方式可以參考文檔
圖片上傳-Image Upload doc

自定義圖片上傳文檔-Custom image upload adapter
upload adapter需要實現UploadAdapter interface里的
abort() upload()方法

import { HttpParams, HttpClient } from "@angular/common/http";
export class UploadAdapter {
    constructor(
      private loader,
      public url:string,
      private http:HttpClient
      ) {}
//自定義的上傳文件方法,可以根據需要封裝
  uploadFile(file,url?:string,user?:string){
    let name = '';
    let formData:FormData = new FormData();
    let headers = new Headers();
    name = file.name;
    formData.append('file', file, name);
    const dotIndex = name.lastIndexOf('.');
    const fileName  = dotIndex>0?name.substring(0,dotIndex):name;
    formData.append('name', fileName);
    formData.append('source', user);
    headers.append('Content-Type', 'multipart/form-data');
    headers.append('Accept', 'application/json');
    let params = new HttpParams();
    const options = {
        params: params,
        reportProgress: true,
    };
    return this.http.post(url,formData,options);
  }
//upload需要返回一個Promise對象,我用的httpClient.post返回值是Obeserver對象,把結果轉成Promise
//封裝的不太好,其實Obeserver可以直接轉為Promise
// 上傳成功返回圖片url一定要以{ default: result['urls']}返回給Promise對象否則會報錯
  upload() {
      let upload = new Promise((resolve, reject)=>{
        this.loader['file'].then(
            (data)=>{
                this.uploadFile(data,this.url,'')
                .subscribe(
                    (result)=>{
                        resolve({ default: result['urls']})
                    },
                    (error)=>{
                        reject(data.msg);
                    }
                );
            }
        );
      });
      return upload;
  }
  abort() {
      console.log("abort")
  }
  }

實現二:直接創(chuàng)建Editor

 <div class="document-editor">
    <div #toolbar class="document-editor__toolbar"></div>
    <div class="document-editor__editable-container">
        <div #documentEditor class="document-editor__editable editor"
        [(ngModel)]="contentText"
        >
    </div>
    </div>
</div> 
//component使用classic editor
constructor()
{
   let MyCustomUploadAdapterPlugin = ( editor )=> {
      editor.plugins.get( 'FileRepository' ).createUploadAdapter = ( loader ) => {
          return new UploadAdapter( loader,'',this.http );
      };
    }
    const editorElement = this.editorItem.elementRef.nativeElement;
    this.Editor.create(
      editorElement,{
        // toolbar: ['imageUpload'],
        extraPlugins:[MyCustomUploadAdapterPlugin]//自定義image uploadAdapter配置在extraPlugins中
       //使用ckfinder配置如下
        // ckfinder:{
        //   uploadUrl:“your server url”,
        //   // options:{
        //   //   resourceType: 'Images'
        //   // }
        // },
      }
    ).then((result) => {
      console.log("success",result,this.Editor);
    }).catch((err) => {
      console.log("err",err);
    });
}
//使用DecoupledEditor
    const el = this.documentEditor.nativeElement
    DecoupledEditor
    .create( el, {
    } )
    .then( editor => {
        const toolbarContainer = this.toolbar.nativeElement;
        toolbarContainer.appendChild( editor.ui.view.toolbar.element );
        this.Editor = editor;
        this.Editor.plugins.get('FileRepository').createUploadAdapter = (loader)=> {
          return new UploadAdapter(loader,this.url,this.http);
        };
    } )
    .catch( err => {
        console.error( err );
    } );

設置Editor高度的時候,如果按照官方文檔設置,由于image caption中也是editor所以會出現image caption太長的情況,設置Editor可以暫時采用這種方式,后續(xù)更新后可采用更好的方法
設置編輯框高度

:host ::ng-deep .ck-editor__editable {
    border: 1px solid gainsboro;
}
:host ::ng-deep .ck-editor__editable:not(.ck-editor__nested-editable) {
    min-height: 500px !important;
}

Angular中展示富文本

對于富文本字符串要進行轉換之后才可以正常顯示樣式,否則可能存在文本的樣式丟失

<div [innerHTML]='reportContent | safeHtml'></div>
import { Pipe, PipeTransform } from "@angular/core";
import { DomSanitizer } from '@angular/platform-browser';
 
// https://angular.io/guide/security
@Pipe({ name: 'safeHtml' })
export class SafeHtmlPipe implements PipeTransform {
  constructor(private sanitized: DomSanitizer) { }
 
  transform(value) {
    // img圖片自適應,組件中的元素樣式對于innerHTML追加的元素無效
    value = value.replace(/\<img/gi,'<img style="max-width:100%;" ');
    return this.sanitized.bypassSecurityTrustHtml(value);
  }
}

Reference & Recommend Reading

disallowcontent
如何與angular結合
ckeditor5-angular如何上傳圖片

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容