使用Angular构建Markdown编辑器

作者 : IT 大叔 本文共6329个字,预计阅读时间需要16分钟 发布时间: 2020-09-22

在这篇文章中,我将指导您完成使用Angular构建Markdown编辑器的过程。

这就是Markdown文本编辑器的外观。

使用Angular构建Markdown编辑器插图

查看有关Jira clone的所有教程

源代码和演示

  1. https://stackblitz.com/edit/angular-markdown-editor-jira
  2. text-editor.component.html

Markdown编辑器模块

Markdown文本编辑器可能会在Web应用程序的许多地方重复使用。为此,我将创建一个全新的模块MarkdownEditorModule。目前,它只有一个组件MarkdownEditorComponent,也将被导出。

使用Angular构建Markdown编辑器插图(2)

其模块和组件内部没有太多代码。

markdown-editor.component.ts

@Component({
  selector: 'markdown-editor',
  templateUrl: './markdown-editor.component.html',
  styleUrls: ['./markdown-editor.component.css'],
})
export class MarkdownEditorComponent implements OnInit {
  ngOnInit() {}
}

markdown-editor.module.ts

@NgModule({
  imports: [CommonModule],
  exports: [MarkdownEditorComponent],
  declarations: [MarkdownEditorComponent],
})
export class MarkdownEditorModule {}

不用担心,我们将在下面添加更多代码。

Github Markdown工具栏

安装@ github / markdown-toolbar-element并在我们的Angular组件中使用它

@nartc建议我使用该软件包启用markdown工具栏。我看了一下,真的很喜欢那个小包装,而且它来自Github本身😊

要将其添加到Angular应用程序中,只需运行

npm install --save @github/markdown-toolbar-element

其次,你需要导入@github/markdown-toolbar-elementMarkdownEditorComponent

import '@github/markdown-toolbar-element'

然后,您可以将以下代码粘贴到中MarkdownEditorComponent

markdown-editor.component.html

<markdown-toolbar for="textarea_id">
  <md-bold>bold</md-bold>
  <md-header>header</md-header>
  <md-italic>italic</md-italic>
  <md-quote>quote</md-quote>
  <md-code>code</md-code>
  <md-link>link</md-link>
  <md-image>image</md-image>
  <md-unordered-list>unordered-list</md-unordered-list>
  <md-ordered-list>ordered-list</md-ordered-list>
  <md-task-list>task-list</md-task-list>
  <md-mention>mention</md-mention>
  <md-ref>ref</md-ref>
</markdown-toolbar>
<textarea id="textarea_id"></textarea>

因为markdown-toolbar是一个自定义Web元素标签,它看起来像一个Angular组件选择器。Angular在其他地方找不到声明,这就是为什么您看到该错误的原因。

使用Angular构建Markdown编辑器插图(4)

要解决此问题,请按照屏幕上的错误将其添加CUSTOM_ELEMENTS_SCHEMAMarkdownEditorModule

@NgModule({
  //code removed for brevity
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})

现在,UI上正在呈现某些内容,并且在工具栏上进行选择后,textarea会得到更新,但是看起来还不太好。

使用Angular构建Markdown编辑器插图(6)

标记降价工具栏样式

为了简化样式设置,我为class设置了一个按钮,.btn并将文本包装为button。我还使用Boostrap Icon使其看起来像一个真正的工具栏。markdown-editor.component.html由于所有图标都是SVG,因此变得越来越长,我不会在此处粘贴所有图标。看看一个大胆的图标,您会明白的。

<markdown-toolbar for="textarea_id">
  <md-bold>
    <button class="btn">
    <svg width="1em"
          height="1em"
          viewBox="0 0 16 16"
          class="bi bi-type-bold"
          fill="currentColor"
          xmlns="http://www.w3.org/2000/svg">
        <path d="M8.21 13c2.106 0 3.412-1.087 3.412-2.823 0-1.306-.984-2.283-2.324-2.386v-.055a2.176 2.176 0 0 0 1.852-2.14c0-1.51-1.162-2.46-3.014-2.46H3.843V13H8.21zM5.908 4.674h1.696c.963 0 1.517.451 1.517 1.244 0 .834-.629 1.32-1.73 1.32H5.908V4.673zm0 6.788V8.598h1.73c1.217 0 1.88.492 1.88 1.415 0 .943-.643 1.449-1.832 1.449H5.907z" />
    </svg></button>
  </md-bold>
  <!-- code removed for brevity -->
</markdown-toolbar>
$hover-color: #06c;

markdown-toolbar {
  padding: 8px;

  .btn {
    background: none;
    border: none;
    cursor: pointer;
    display: inline-block;
    height: 24px;
    padding: 3px 5px;
    width: 28px;
    color: #222;

    i {
      display: flex;
    }

    &:hover {
      color: $hover-color;
    }
  }
}

在对文本区域进行如下样式设置后,您将看到一个相当令人满意的结果result

样式化文本区域

我还将为textarea进行样式设计。

首先,我为该text-editor文本区域分配一个类。

<textarea id="textarea_id"
          class="text-editor">
</textarea>

对于CSS,我想要:

  • 文本区域无边框
  • 在标记工具栏和文本区域周围具有容器的边框
  • 悬停文本区域时,为容器设置不同的边框颜色

我希望我的CSS能够表达自己的意思:)但是,如果您对CSS有任何疑问,请在下面的评论框中告诉我。

$border-color: #d9d9d9;

:host {
  border: 1px solid $border-color;
  box-shadow: 0 0 0 1px $border-color;
  border-radius: 3px;
  outline: none;
  background: #fff;
  display: flex;
  flex-direction: column;  

  .text-editor {
    padding-left: 15px;
    padding-right: 15px;
    resize: none;
    border-color: transparent;
    width: 100%;
    overflow-y: hidden;

    &:focus {
      outline: none;
      border: transparent;
    }
  }

  &.focus {
    border: 1px solid $hover-color;
    box-shadow: 0 0 0 1px $hover-color;
  }
}

我现在有结果,看起来还不错。但是,当我选择文本区域时,边框颜色没有改变。

使用Angular构建Markdown编辑器插图(8)

为什么?因为我们需要为textarea类设置一个额外的类。我们要:

  • 处理focustextarea的事件以添加一个命名.focus为父容器的类。
  • 还处理blur事件以从父容器中删除此类。

我还cdkTextareaAutosize@ angular / cdk / text-field包中添加了内容,以使textarea在内容太长时自动扩展其高度。默认情况下,textarea将显示一个滚动条,并且不会自动展开。在我之前的教程中了解更多内容- 构建可编辑的文本框。我还将设置cdkAutosizeMinRows为6,以便它也将具有一定的最小高度。

<textarea class="text-editor"
          (focus)="focus()"
          (blur)="blur()"
          [formControl]="control"
          id="MarkdownInput"
          cdkTextareaAutosize
          [cdkAutosizeMinRows]="6">
</textarea>
export class MarkdownEditorComponent implements OnInit {
  @HostBinding('class.focus') isFocus: boolean;
  focus() {
    this.isFocus = true;
  }
  blur() {
    this.isFocus = false;
  }
}

要做的HostBinding是检查是否isFocus为真,然后Angular将向focus组件选择器添加一个类名。看起来像<markdown-editor class="focus。如果该值为false,则删除该类。

使用Angular构建Markdown编辑器插图(10)

我想我们快到了,现在看起来很棒。最后一件事是将此组件与表单连接。

将markdown编辑器组件链接到表单

通常,Markdown编辑器将用于具有一些附加表单输入的表单中,并且您希望在表单实例中查看其值。

为此,只需将设置MarkdownEditorComponent为接受输入,即FormControl。这样控件就可以从父组件表单实例传递到组件中。

FormControl如果未传递任何输入,则组件将初始化默认值。

export class MarkdownEditorComponent implements OnInit {
  @Input() control: FormControl;
  ngOnInit(): void {
    this.control = this.control ?? new FormControl();
  }
}

并将控件绑定到组件HTML

<textarea id="textarea_id"
          class="text-editor"
          [formControl]="control"
          (focus)="focus()"
          (blur)="blur()"
          cdkTextareaAutosize
          [cdkAutosizeMinRows]="6">
</textarea>

为了能够做到这一点,你必须导入ReactiveFormsModuleMarkdownEditorModule

@NgModule({
  imports: [
    CommonModule,
    ReactiveFormsModule
  ],
  //code removed for brevity
})
export class MarkdownEditorModule { }

为了用表单测试它,我将创建一个简单的表单,其中包含两个输入FormBuilder

  • 标题作为普通文本框
  • 描述为降价编辑器
export class AppComponent implements OnInit {
  form: FormGroup;
  constructor(private _fb: FormBuilder) {}

  ngOnInit() {
    this.form = this._fb.group({
      title: ["Hello, I am Trung", Validators.required],
      description: ["This is a markdown text editor for - http://jira.trungk18.com/"]
    });
  }

  get descriptionControl(){
    return this.form.controls.description as FormControl
  }
}

我还从表单中获取了描述控件,然后将其发送到 MarkdownEditorComponent

<form [formGroup]="form">
  <div class="form-group">
    <label for="Title">Title</label>
    <input formControlName="title" class="form-control" id="Title" aria-describedby="Title">
  </div>
  <div class="form-group">
    <label>Description</label>
    <markdown-editor [control]="descriptionControl"></markdown-editor>
  </div>
</form>
<div class="alert alert-info">
  {{ form.value | json }}
</div>

太好了,一切似乎都按预期进行。

使用Angular构建Markdown编辑器插图(12)

辅助功能

最后但并非最不重要的一点,请记住为所有图标添加aria-labeltitle。否则,如果用户不熟悉文本编辑图标,则可能会难以理解其含义。该aria-label是对残疾人士可以通过您的网站有一个简单的导航:)

<markdown-toolbar for="textarea_id">
  <md-bold>
    <button class="btn" title="Bold" aria-label="Bold">
    <svg width="1em"
          height="1em"
          viewBox="0 0 16 16"
          class="bi bi-type-bold"
          fill="currentColor"
          xmlns="http://www.w3.org/2000/svg">
        <path d="M8.21 13c2.106 0 3.412-1.087 3.412-2.823 0-1.306-.984-2.283-2.324-2.386v-.055a2.176 2.176 0 0 0 1.852-2.14c0-1.51-1.162-2.46-3.014-2.46H3.843V13H8.21zM5.908 4.674h1.696c.963 0 1.517.451 1.517 1.244 0 .834-.629 1.32-1.73 1.32H5.908V4.673zm0 6.788V8.598h1.73c1.217 0 1.88.492 1.88 1.415 0 .943-.643 1.449-1.832 1.449H5.907z" />
    </svg></button>
  </md-bold>
  <!-- code removed for brevity -->
</markdown-toolbar>

现在,当您有时将鼠标悬停在图标上时,浏览器将显示标题。

使用Angular构建Markdown编辑器插图(14)

这就是用Angular构建Markdown编辑器的全部。

免责声明:
1. 本站资源转自互联网,源码资源分享仅供交流学习,下载后切勿用于商业用途,否则开发者追究责任与本站无关!
2. 本站使用「署名 4.0 国际」创作协议,可自由转载、引用,但需署名原版权作者且注明文章出处
3. 未登录无法下载,登录使用金币下载所有资源。
IT小站 » 使用Angular构建Markdown编辑器

常见问题FAQ

没有金币/金币不足 怎么办?
本站已开通每日签到送金币,每日签到赠送五枚金币,金币可累积。
所有资源普通会员都能下载吗?
本站所有资源普通会员都可以下载,需要消耗金币下载的白金会员资源,通过每日签到,即可获取免费金币,金币可累积使用。

发表评论