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';