Angular6 + Editor.md markdown Directive指令实现

柯振濂
2023-12-01

Angular6 + Editor.md angular markdown directive指令方法


想要在angular中使用Markdown编辑器,怪我太笨,搞了三天才算有了自己想要的结果,主要是使用了Editor.md,其中碰到了一些坑,觉得有必要记录一下.有两种方法,一种是editor.md作为指令Directive进行构建,还有一种是使用自定义表单集成Editor.md.(方法)…比较的困难,没有做尝试.

以下仅为一个小白的个人理解,轻喷


Angular github搜罗的库
Angular其实本身是有编辑器的,很简易的编辑器,直接百度搜angular markdown就能找到,支持的功能比较少,angular官网所收罗的库只有一个markdown的解析器而不是编辑器,就很蛋疼了…
官网给出了几个editor,还是非常好看强大的,也可以用那个,应该比较简单,我没尝试过.
基本教程
方法就是按照这个来做的,把编辑器作为一个指令插入到angular里面去,成功的原理我还不明白.

  1. CSDN的markdown编辑器并不是使用的editor.md,而是StackEditor,个人认为还是StackEditor的编辑器更加好看一点.
  2. 使用文章中的EditorConfig作为参数传递给函数的方法在我这里没有成功,不知道为什么,所以我都直接在默认的文件里面改了…

其实主要在改的东西就是工具栏,我不想在工具栏之外的地方添加保存,上传这两个功能,就想自定义工具栏添加俩点击事件,结果是真他妈麻烦…
关键词: 生命周期 属性监听 Promise
自定义工具栏的基本方法在editor.md的官网上有.我的步骤如下.

  1. toolbarCustomIcons更改
    添加两个Button的html标签,不能直接在属性里面写mat-button,angular并不会编译这一个属性
    (因为这是editormd.js方法动态生成的button,已经错过了angular解释button的时期,所以只是作为一个字符串显示出来而已即使button会被浏览器识别到…)
    所以只好在button上添加class=".mat-button"改变样式.
      toolbarIconTexts     : {
         save: "<button type='button' class='mat-button' id='saveButton'>保存</button>",
         upload: "<button type='button'  class='mat-button' id='uploadButton'>上传</button>",
       },
  1. editormd.toolbarModes更改
在这个数组的full属性里面添加上自己定义的toolbar的name..
        full : [
   			...
           "help", "info","|","save","upload","save1",
           ],
           ......
接着在    editormd.defaults  属性下的        toolbarIcons         :"full",设置为full
  1. toolbarHandlers不做处理
    因为要在angular里面处理这两个按钮的事件,所以不得在这里进行处理点击事件.
  2. 关键点,如何绑定click事件
    这里太他妈痛苦了,也怪我太笨,查了好久…
  1. 首先要知道angular的生命周期,编辑器其实是根据当前已有的<div id=editor>调用方法editormd添加上各种各样的html标签和方法而已…也就是说调用这个方法之前,dom中必须已经存在这个div,所以在angular的constructor里面调用不行,需要在oninit或其之后的生命
    周期之中调用这个方法才行.
  2. editormd方法的调用比较蛋疼,我加了断电查了好久才知道原来是先返回一个init,然后方法会动态的加载各类文件(异步),加载完之后才会正常的渲染显示整个编辑器,可以查看源码中的loadQueue和之后的loadDIsplay方法…也就是说这个方法的内部的几个方法是异步执行的,不知道什么时候会结束…这就导致了直接使用id进行事件绑定的话,会出错找不到这个id,因为异步过程还未执行完毕(但editormd方法已经执行完毕了…),dom中不存在这个元素…
  3. 查资料查到了Promise方法,这个方法允许做出承诺,承诺代码体内的事件完成之后的状态,这里我之前一直混淆了概念,认为异步执行是方法执行完成了,其实并没有,异步只是说明在后台多线程运行而已,但还是一直在运行,并没有返回值…所以不能使用这个方法(反正我不会)…editormd的源码已经写好了,也不能轻易更改,重要的是不知道在哪里更改才行…
  4. 又看源码才知道editormd方法返回的对象里面有一个state属性,标志着editor的解析状态,如果是loaded说明已经解析完毕,整个方法结束了…所以可以对这个属性进行监听,如果说状态改变才会绑定时间,这样就轻松多了.
  5. 属性监听的方法有三种 参考资料 ,Object.defineProperty,已经废弃的observe,还有代理方法.其中代理方法在这里并不适用,因为人家的代码已经写好了,没法改…所以考虑使用Object.defineProperty方法进行监听editor.state属性…
  6. 监听并且绑定上事件了.
 ngOnInit(): void {
   this.editor = editormd(this.id, {
 });
  Object.defineProperty(this.editor.state, 'loaded',  {
   set: function (value) {
       if (value === true) {
         document.getElementById('saveButton').onclick = function () {
           console.log('绑定事件成功');
         };
       }
     }
   });
  1. 现在可以往这个Directive里面注入服务等,做相关的一些东西了.总结: 基础真他妈重要…现在还是狗屁不懂…我操.

设置markdown的非编辑模式


委实把我给坑惨了,虽然很感谢作者写了个很好用的开源工具出来,但是官方文档是真不给力啊.好几个示例的链接都失效了,按理来说不会没人给作者说吧?还有就是为什么几乎所有的示例都有代码而单单markdown-to-html示例的没有代码,只有一个完整的显示后的页面?这让我很蛋疼啊,还得自己去百度资料.
这其中又遇到几个坑,我操,心累啊.

  1. 我原本以为还会像editormd这个构造方法一样会自动的加载所有需要的js文件,看来我错了…需要手动加载.可以选择在index.html里面添加路径,由于使用的是angular,所以在angular.json里面添加了js文件.
  2. 需要注意的是,这些依赖的包的加载是有顺序的,后边的包依赖前面的包,来回搞了几次,总算可以了.按照这个顺序导入是没有问题的.
             "src/assets/editor.md-master/editormd.js",
             "src/assets/editor.md-master/lib/flowchart.min.js",
             "src/assets/editor.md-master/lib/jquery.flowchart.min.js",
             "src/assets/editor.md-master/lib/marked.min.js",
             "src/assets/editor.md-master/lib/prettify.min.js",
             "src/assets/editor.md-master/lib/raphael.min.js",
             "src/assets/editor.md-master/lib/underscore.min.js",
             "src/assets/editor.md-master/lib/sequence-diagram.min.js"
 类似资料: