AngularJs 12 使用 Editor.md 并拆分为组件,解决 editormd.setValue 不存在的bug

参考

  1. editor.md 官网
  2. Angular集成Editor.md的Markdown编辑器,支持NgModel双向绑定
  3. 使用editor.md踩坑血泪史总结

文章前的闲聊

接上一篇文章《AngularJs 12 使用 Editor.md 实现 Markdown 编辑器》实现。之后,发现其他页面还需要引用到(编辑页面、创建页面、前端渲染也需要用到)。
本文只是做了一个简单的封装,配置并没有增加参数绑定实现传入配置。建议参考《Angular集成Editor.md的Markdown编辑器,支持NgModel双向绑定》这篇文章。

代码

  1. 简单的ts类型接口定义文件 admin-editormd/editormd-type.ts,用来实现代码提示。
/**
 * 定义基本编辑器接口实现类型提示
 */
export interface EditormdType {
  getMarkdown(): string;
  setValue(str:string): EditormdType;
}
  1. 组件的js代码 admin-editormd/admin-editormd.component.ts在组件 ngOnInit()方法 中,初始化完毕组件之后,页面应该还没有渲染完毕(可能的原因),所以需要用计时器去判断页面是否加载完毕,加载完毕后就调用父页面的方法将实例传回父页面,让父页面进行渲染数据(暂时没有想到其他好办法)
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { EditormdType } from './editormd-type';
declare var $: any;
declare var editormd: any;
@Component({
  selector: 'app-admin-editormd',
  templateUrl: './admin-editormd.component.html',
  styleUrls: ['./admin-editormd.component.scss']
})
export class AdminEditormdComponent implements OnInit {
  /**
   * 编辑器实例
   */
  public editormd: EditormdType | undefined;
  @Output() onBindEditormdInstance = new EventEmitter<any>();

  constructor() { }

  ngOnInit() {
    this.editormd = editormd("editormd", {
      data: "",
      width: "100%",
      height: 520,
      syncScrolling: "single",
      path: "./assets/editormd/lib/",
      imageUpload: true,
      imageFormats: ["jpg", "jpeg", "gif", "png", "bmp"],
      imageUploadURL: "api/upload/mdupload?test=dfdf",
      emoji: true,
      taskList: true,
      tex: true,  // 默认不解析
      flowChart: true,  // 默认不解析
      sequenceDiagram: true,  // 默认不解析SS
    });
    /**
     * 这里是因为编辑器加载对象完毕之后,页面还没渲染完毕。。所以每隔一定时间去判断是否渲染完毕,我好菜阿
     */
    console.log("编辑器渲染启动:",(new Date()).getSeconds()+"s_"+(new Date()).getMilliseconds()+"ms");
    const sendEvent = setInterval(()=>{
      try {
        this.editormd?.setValue("");
        console.log("编辑器渲染完毕:",(new Date()).getSeconds()+"s_"+(new Date()).getMilliseconds()+"ms");
        this.onBindEditormdInstance.emit(this.editormd);
        clearInterval(sendEvent);
      } catch (error) {

      }
    }, 50);
  }
}
  1. 组件的html代码 admin-editormd/admin-editormd.component.html
<div class="app-admin-editormd">
  <div class="admin-editormd-container">
    <div id="editormd"></div>
  </div>
</div>
  1. 父组件 js代码 admin-article-edit/admin-article-edit.component.ts,子组件会调用父组件的 onBindEditormdInstance() 方法,调用的时候就获取页面数据可以进行渲染了
import { Component, OnInit } from '@angular/core';
import { AdminArticleService } from '../../../services/admin-article.service';
import { Router, ActivatedRoute, NavigationEnd } from '@angular/router'; //导入router服务
@Component({
  selector: 'app-admin-article-edit',
  templateUrl: './admin-article-edit.component.html',
  styleUrls: ['./admin-article-edit.component.scss']
})
export class AdminArticleEditComponent implements OnInit {
  public id = 0;
  public title = "";
  public introduction = "";
  public editormd: any;
  //
  constructor(protected router: Router, private adminArticleService: AdminArticleService, private activatedRoute: ActivatedRoute) { }

  ngOnInit() {
  }
  /**
   * 子组件初始化成功后将实例返回
   */
  onBindEditormdInstance(editormd: any) {
    this.editormd = editormd;
    this.onGetArticleInfo();
  }
  /**
   * 获取文章数据
   */
  onGetArticleInfo() {
    let id = Number(this.activatedRoute.snapshot.paramMap.get('id'));
    this.adminArticleService.getArticle(id).then(res => {
      this.id = id;
      this.title = res.data.title;
      this.introduction = res.data.introduction;
      this.editormd.setValue(res.data.content);
    });
  }
  /**
   * 保存
   */
  onSave() {
    this.adminArticleService.editArticle(this.id, {
      title: this.title,
      introduction: this.introduction,
      content: this.editormd.getMarkdown(),
    }).then(res => {
      history.go(-1);
    });
  }

}
  1. 父组件 html代码 admin-article-edit/admin-article-edit.component.html
<div class="app-admin-article-edit">
  <div class="admin-article-edit-container">
    <div class="forms">
      <div class="item">
        <input dTextInput placeholder="标题" id="textInput" [(ngModel)]="title"/>
      </div>
      <div class="item">
        <textarea dTextarea placeholder="描述" id="textArea" [(ngModel)]="introduction"></textarea>
      </div>
      <div class="item">
        <app-admin-editormd (onBindEditormdInstance)="onBindEditormdInstance($event)"></app-admin-editormd>
      </div>
      <div class="item">
        <d-button id="primaryBtn" style="margin-right: 8px" (click)="onSave()">保存</d-button>
      </div>
    </div>
  </div>
posted @ 2021-08-20 22:30  夏秋初  阅读(195)  评论(0编辑  收藏  举报