引言

原项目集成TinyMCE,但公式录入需要购买昂贵的MathType或自研插件,遂启用UEditor,集成开源的公式插件。

UEditor对三大框架的支持不是很好,也尝试了ngx-ueditor,用完之后的结论,我不用这个东西。

总结出一句话:TSANY,整死程序员。

如果想通过ngx-ueditor集成,请参考angular 使用 ueditor - 鲸冬香

原生集成

下载Demo

进入官网,在下载页下载示例代码。

UEditor是基于MIT协议开源的,被授权人可以使用、复制、修改、合并、出版发行、散布、再授权及贩售软件及软件的副本,且可以自由地修改源代码

集成

将前端代码拷贝至src/assets/ueditor目录下。

编辑angular.json文件,定位到projects->web->architect->build->options->scripts数组下:

添加如下配置,将ueditor加入到项目构建中。

"src/assets/ueditor/ueditor.config.js",
"src/assets/ueditor/ueditor.all.min.js",
"src/assets/ueditor/lang/zh-cn/zh-cn.js"

注:ueditor.config.js一定要在ueditor.all.min.js之前引入,否则window.UE对象会被覆盖。

组件替换

原项目将TinyMCE封装成Editor组件,现在需要将Editor组件的内部实现替换为UEditor

官方文档上来一个script给我整懵圈了,容器怎么能用script呢?

经测试,官方文档的写法是错误的,不能使用script当容器。

每个编辑器都应该配置唯一id,用于查找DOM,构建编辑器实例。

ngOnInit方法中,请求生成唯一id

/** 请求唯一 id */
this.editorId = 'editor-' + this.commonService.getUniqueId();
<div [id]="editorId"></div>

ngAfterViewInit方法中构造编辑器,需要页面渲染之后,UEditor才能根据id构造编辑器,并设置事件监听。

/** 实例化 UEditor */
this.editor = UE.getEditor(this.editorId);
/** ready 时触发方法 */
this.editor.ready(() => {
  /** 设置内容 */
  this.editor.setContent(this.content);
  /** 添加输出监听器 */
  this.editor.addListener('contentChange', () => {
    this.contentEmit();
  });
});

图片上传

按照官方的描述,后台配置一个接口,根据不同的action返回不同的数据。

后台配置handler,根据不同的action转发给不同的方法。

@RequestMapping
public Object handler(@RequestParam(value = "action", required = false) String action,
                      @RequestParam(value = "attachment", required = false) MultipartFile multipartFile) {
    if (KEY_CONFIG.equals(action)) {
        return this.getConfig();
    }
    if (KEY_UPLOAD.equals(action)) {
        return this.uploadImage(multipartFile);
    }

    throw new RuntimeException("未传入正确的 action");
}

/**
 * 获取配置信息
 */
private Config getConfig() {
    logger.debug("返回配置信息");
    Config config = new Config();
    config.setImageActionName(KEY_UPLOAD);
    config.setImageFieldName("attachment");
    config.setImageUrlPrefix("");
    config.setImageAllowFiles(Arrays.asList(".png", ".jpg", ".jpeg", ".gif", ".bmp"));
    return config;
}

private UEditorImage uploadImage(MultipartFile multipartFile) {
    if (multipartFile == null || multipartFile.isEmpty()) {
        return null;
    }
    logger.debug("上传附件");
    Attachment attachment = this.attachmentService.upload(multipartFile);

    logger.debug("图片存储");
    UEditorImage image = new UEditorImage();
    image.setState("SUCCESS");
    image.setTitle(attachment.getName());
    image.setOriginal(attachment.getOriginName());
    image.setUrl(String.format("/%s/%s/%s/%s/%s/%s",
            properties.getPrefix(),
            properties.getAttachment(),
            attachment.getMd5(),
            attachment.getSha1(),
            attachment.getId(),
            attachment.getOriginName()));
    return image;
}

ueditor.config.js文件中配置图片服务器接口地址。

// 服务器统一请求接口路径
serverUrl: "/api/ueditor"

集成插件

将整个插件放入ueditor目录下。

将插件集成到angular.json文件中。

"src/assets/ueditor/kityformula-plugin/addKityFormulaDialog.js",
"src/assets/ueditor/kityformula-plugin/getKfContent.js",
"src/assets/ueditor/kityformula-plugin/defaultFilterFix.js"

总结

UEditor集成较复杂,可能不再适合当前环境,期待下一代富文本编辑器的发展。

03-05 14:41