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如何上传图片