当前位置: 首页 > 工具软件 > mdEditor > 使用案例 >

md.editor组件

微生运浩
2023-12-01

editor-config.ts:

declare var editormd: any;


export class EditorConfig {
  public width = '100%';
  public height = '400'; // no,自适宜h
  public path = 'assets/editor.md/lib/'; // 正确的lib文件件
  public codeFold = true;
  public searchReplace = false;  // false
  public toolbar = true;
  public emoji = false; // false
  public taskList = true;
  public tex = false; // false
  public readOnly = false;
  public tocm = false; // false
  public watch = true;
  public previewCodeHighlight = true;
  public saveHTMLToTextarea = true;
  // public markdown = ''; // no
  // public flowChart = true; // false
  // public syncScrolling = true;
  // public sequenceDiagram = true;
  // public imageUpload = true; // false
  // public imageFormats = ['jpg', 'jpeg', 'gif', 'png', 'bmp', 'webp']; // no
  // public imageUploadURL = ''; // no


  htmlDecode=true;
  toolbarIcons(){
    // Or return editormd.toolbarModes[name]; // full, simple, mini
    // Using "||" set icons align right.
    // return ["undo", "||", "watch", "fullscreen", "preview"]
    return editormd.toolbarModes['simple'];
  }

 /* toolbarIconsClass = {
    undo: 'anticon anticon-rollback',
    watch: 'anticon anticon-eye',
    unwatch: 'anticon anticon-eye-o',
    fullscreen: 'anticon anticon-scan',
    preview: 'anticon anticon-play-circle-o'
  }*/
  constructor() {
  }

  public onload() {
  }

  public onchange() {
  }
}

HTML:

<div id="md" #host class="md-ks"> </div>

css:

//:host ::ng-deep

// 类名:
// 最外层:editormd editormd-vertical
//
// 左侧编辑:CodeMirror cm-s-default CodeMirror-wrap
//
//
// 右侧:editormd-preview
//
// toolbar:editormd-toolbar

:host ::ng-deep .md-ks{
  li{
    list-style: square;
  }

  // 右侧:
  .editormd-preview{
    // a标签
    a {
      color: #42b983;
      //font-weight: 600;
      padding: 0px 2px;
      text-decoration: none;
    }
    // 点击a不让跳转
    .pointer-event-none a{
      pointer-events: none;
    }

    // 代码块没有隔行高亮
    li.L1, li.L3, li.L5, li.L7, li.L9 {
      background: #f6f6f6;
    }
  }

}

ts:

import {
  AfterViewInit, Component, ElementRef, EventEmitter,
  forwardRef, Input, NgZone, OnDestroy, OnInit, Output,
  ViewChild
} from '@angular/core';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
import {EditorConfig} from './editor-config';

declare var editormd: any;


const UEDITOR_VALUE_ACCESSOR = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => MarkdownComponent),
  multi: true
};

export const md_one = `
**简要描述:** 
- 请在此输入api接口内容概要
我是第一种模型
`
export const md_two = `
**简要描述:** 
- 请在此输入api接口内容概要
我是第二种模型
`

@Component({
  selector: 'app-markdown',
  templateUrl: './markdown.component.html',
  styleUrls: ['./markdown.component.scss'],
  providers: [UEDITOR_VALUE_ACCESSOR]
})
export class MarkdownComponent implements AfterViewInit, OnDestroy, ControlValueAccessor {

  @Input() editormdConfig: EditorConfig; // 配置选项
  /**
   * 默认函数
   */
    // tslint:disable-next-line:no-output-on-prefix
  @Output() onReady = new EventEmitter();
  // tslint:disable-next-line:no-output-on-prefix
  @Output() onValueChange = new EventEmitter();
  // tslint:disable-next-line:no-output-on-prefix
  @Output() onFocus = new EventEmitter();
  @Output() getHtmlValue = new EventEmitter();

  @ViewChild('host') host; // 获取dom元素

  private mdeditor: any; // md的实例
  private value: string; // md的值

  // 两种模式(编辑和可读)
  @Input() mode: 'default' | 'display' = 'default';
  // 默认值
  @Input() defaultMd= md_one;

  constructor(private el: ElementRef,
              private ngZone: NgZone) {

  }

  /**
   * 与md相关的逻辑处理函数:需要static。
   */
  static joinStr(json={
    developer: '',
    contactInformation: '',
    repositoryUrl: '',
    codeBranch: '',
    gatewayUrl: '',
    reqType: '',
  }){
    let str='';
    if(!!json.developer){
      str+=`* 作者:${json.developer}\n`;
    }
    if(!!json.contactInformation){
      str+=`* 联系方式:${json.contactInformation}\n`;
    }
    if(!!json.repositoryUrl){
      str+=`* 仓库地址:${json.repositoryUrl}\n`;
    }
    if(!!json.codeBranch){
      str+=`* 代码分支:${json.codeBranch}\n`;
    }
    if(!!json.gatewayUrl){
      str+=`* 请求URL:${json.gatewayUrl}\n`;
    }

    const mdStr=`
${str}
${!!str?'---':''}
`
    return mdStr;
  }

  ngAfterViewInit() {
    console.log(this.mode);
    this.init();
  }

  ngOnDestroy() {
    this.destroy();
  }

  init() {
    if (typeof editormd === 'undefined') {
      console.error('UEditor is missing');
      return;
    }
    this.editormdConfig = this.editormdConfig != null ? this.editormdConfig : new EditorConfig();
    if (this.mode == 'display') {
      this.editormdConfig.readOnly = true; // 这样设置,是为了display的时候,没有右上角的“x"号
    }

    console.log("配置:", this.editormdConfig);
    this.editormdConfig.onload = () => {

      // ksbk-两种模式:display 和 default模式。需要在这做判断
      if (this.mode == 'display') {
        console.log('zhixingleme ?');
        this.mdeditor.previewing(); // display模式
      } else {

      }
      if (this.value) {
        this.mdeditor.setMarkdown(this.value);
      }
      // ksbk-指定默认值
      if(!this.value&&this.mode!='display'){
        this.mdeditor.setMarkdown(this.defaultMd);
      }
    };
    this.editormdConfig.onchange = () => {
      this.updateValue(this.mdeditor.getMarkdown());
    };
    this.mdeditor = editormd(this.host.nativeElement.id, this.editormdConfig); // 创建编辑器

  }

  /**
   * 销毁
   */
  destroy() {
    if (this.mdeditor) {
      // this.mdeditor.removeListener('ready');
      // this.mdeditor.removeListener('contentChange');
      this.mdeditor.editor.remove();
      // this.mdeditor.destroy();
      this.mdeditor = null;
    }

  }

  /**************************默认的函数********************************/
  writeValue(value: string): void {
    this.value = value;
    console.log('value', value);
    if (this.mdeditor) {
      this.mdeditor.setMarkdown(this.value);
    }
  }

  updateValue(value: string) {
    console.log("什么时候执行啊");
    this.ngZone.run(() => {
      this.value = value;

      this.onChange(this.value);
      this.onTouched();

      this.onValueChange.emit(this.value);
      this.getHtmlValue.emit({originalEvent: event, value: this.getHtmlContent()});
    });
  }

  onChange: Function = () => {
    console.log('change执行了');
  };
  onTouched: Function = () => {
  };

  getMarkContent(): string {
    return this.mdeditor.getMarkdown();
  }

  getHtmlContent(): string {
    // console.log('this.mdeditor.getHTML():', this.mdeditor.getHTML());
    return this.mdeditor.getHTML();
  }


  registerOnChange(fn: any): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: any): void {
    this.onTouched = fn;
  }

  setDisabledState?(isDisabled: boolean): void {
    if (isDisabled) {
      this.mdeditor.setDisabled();
    } else {
      this.mdeditor.setEnabled();
    }
  }
}

组件使用:

 <app-markdown [(ngModel)]="mdStr" [mode]="'display'"></app-markdown>

注:
1.display是字符串,不是变量。
2.ngModel使用[]+(),双向绑定。
3.ts中使用MarkdownComponent.joinStr(res)方法。
4.display的时候,readOnly要设置为true,要不然会有“x”号。
5.npm install codemirror

@import "~codemirror/lib/codemirror";
@import "~codemirror/theme/material";
<app-markdown [(ngModel)]="mdStr" [defaultMd]="mdDefaultStr"></app-markdown>


  public mdDefaultStr=md_two;

引入组件里面的方法和常量:

import {MarkdownComponent, md_two} from '../../../../theme/components/markdown/markdown.component';
 类似资料: