• 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: "",
           "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>
    
    如果觉得文章对您有帮助,希望您能 关注+推荐 哦
  • 相关阅读:
    async/await的应用场景
    手写实现js中的instanceof
    性能测试:jvm可视化监控搭建
    Kubernetes 监控:Prometheus Operator + Thanos 实践篇
    Kubernetes 多租户:资源配额
    使用 filebeat原生处理日志时间,就是使用日志文件中message字段值开头的时间覆盖默认的@timestamp时间,使用filebeat processor配置,pipeline不符合要求
    Kubernetes Operator: Operator
    大人物的特征
    Kubernetes 监控:Service Mesh 实践 Istio 流量管理
    kubernetes中部署kubeprometheus项目解决ControllerManager与Scheduler无法监控问题
  • 原文地址:https://www.cnblogs.com/xiaqiuchu/p/15168414.html
Copyright © 2020-2023  润新知