参考
文章前的闲聊
接上一篇文章《AngularJs 12 使用 Editor.md 实现 Markdown 编辑器》实现。之后,发现其他页面还需要引用到(编辑页面、创建页面、前端渲染也需要用到)。
本文只是做了一个简单的封装,配置并没有增加参数绑定实现传入配置。建议参考《Angular集成Editor.md的Markdown编辑器,支持NgModel双向绑定》这篇文章。
代码
- 简单的ts类型接口定义文件
admin-editormd/editormd-type.ts
,用来实现代码提示。
/**
* 定义基本编辑器接口实现类型提示
*/
export interface EditormdType {
getMarkdown(): string;
setValue(str:string): EditormdType;
}
- 组件的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: "",
"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);
}
}
- 组件的html代码
admin-editormd/admin-editormd.component.html
<div class="app-admin-editormd">
<div class="admin-editormd-container">
<div id="editormd"></div>
</div>
</div>
- 父组件 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);
});
}
}
- 父组件 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>