【Angular4+】实现CKEditor5富文本编辑与富文本展示

Angular4+使用CKEditor5实现富文本编辑器

编辑器支持文本输入,基本文本样式:对齐、加粗等;粘贴上传图片等功能,本文图片上传基于自定义的上传方法

CKEditor5提供了几种封装好的不同风格的富文本编辑器

  • Classic editor – ClassicEditor
  • Inline editor – InlineEditor
  • Balloon editor – BalloonEditor
  • Document editor – DecoupledEditor

实现一:使用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:文本框的内容



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;
  @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")
  }
  }

实现二:直接创建Editor

 
//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可以暂时采用这种方式,后续更新后可采用更好的方法
设置编辑框高度

: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中展示富文本

对于富文本字符串要进行转换之后才可以正常显示样式,否则可能存在文本的样式丢失

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(/\

Reference & Recommend Reading

disallowcontent
如何与angular结合
ckeditor5-angular如何上传图片

你可能感兴趣的:(【Angular4+】实现CKEditor5富文本编辑与富文本展示)