(传统) Angular 富文本编辑器组件
⚠️ 我们更改了安装方法,此传统指南是为了方便用户保留的。如果您正在寻找当前的 CKEditor 5 Angular 集成,请参阅最新的 CKEditor 5 集成 指南。
CKEditor 5 包含 即用型编辑器构建 和 CKEditor 5 框架,构建基于该框架。
目前,CKEditor 5 的 Angular 组件仅支持通过构建集成 CKEditor 5。由于无法 调整 angular-cli
中的 webpack 配置,因此无法集成 从源代码构建的 CKEditor 5。
# 支持的 Angular 版本
由于 Angular 库输出格式的重大更改,@ckeditor/ckeditor5-angular
包发布了以下版本以支持各种 Angular 生态系统
CKEditor 5 版本 | Angular 版本 | 详细信息 |
---|---|---|
积极支持的版本 | ||
^6 |
13+ |
需要版本 37 或更高版本的 CKEditor 5。 |
过去版本(不再维护) | ||
^5 |
13+ |
需要版本 13+ 或更高版本的 Angular。较低版本不再维护。 |
^5 |
13+ |
需要版本 13+ 或更高版本的 Angular。较低版本不再维护。 |
^4 |
9.1+ |
需要版本 34 或更高版本的 CKEditor 5。 |
^3 |
9.1+ |
需要版本 14 或更高版本的 Node.js。 |
^2 |
9.1+ |
迁移到 TypeScript 4。声明文件不向后兼容。 |
^1 |
5.x - 8.x |
Angular 版本不再维护。 |
所有可用的 Angular 版本都 列在 npm 上,可以在那里提取。
# 快速入门
在您现有的 Angular 项目中,安装 CKEditor 5 WYSIWYG 编辑器组件 for Angular
npm install --save @ckeditor/ckeditor5-angular
如果您没有现有的项目,可以使用 Angular CLI 创建一个新项目。
安装一个 CKEditor 5 预定义构建 或 创建一个自定义构建。
本教程假设您选择了 @ckeditor/ckeditor5-build-classic
npm install --save @ckeditor/ckeditor5-build-classic
@ckeditor/ckeditor5-angular
包需要以下对等依赖项,版本至少为 37.0.0
@ckeditor/ckeditor5-core
,@ckeditor/ckeditor5-engine
,@ckeditor/ckeditor5-utils
,@ckeditor/ckeditor5-watchdog
.
请记住,它们必须与编辑器构建具有相同的版本。
安装所有必需的对等依赖项
npm install --save @ckeditor/ckeditor5-core @ckeditor/ckeditor5-engine @ckeditor/ckeditor5-utils @ckeditor/ckeditor5-watchdog
现在,将 CKEditorModule
添加到其组件将在模板中使用 <ckeditor>
组件的模块。
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { CKEditorModule } from '@ckeditor/ckeditor5-angular';
import { AppComponent } from './app.component';
@NgModule( {
declarations: [
AppComponent
],
imports: [
BrowserModule,
CKEditorModule
],
providers: [],
bootstrap: [ AppComponent ]
} )
export class AppModule { }
在您的 Angular 组件中导入编辑器构建,并将其分配给一个 public
属性,以便模板可以访问它
// app.component.ts
import { Component } from '@angular/core';
import ClassicEditor from '@ckeditor/ckeditor5-build-classic';
@Component( {
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
} )
export class AppComponent {
title = 'angular';
public Editor = ClassicEditor;
}
最后,在模板中使用 <ckeditor>
标签运行富文本编辑器
<!-- app.component.html -->
<ckeditor [editor]="Editor" data="<p>Hello, world!</p>"></ckeditor>
重建您的应用程序,CKEditor 5 应该会显示“Hello, world!”。
# 使用文档编辑器构建
如果您想使用 文档编辑器构建,您需要 手动将工具栏添加到 DOM。
// app.component.ts
import { Component } from '@angular/core';
import DecoupledEditor from '@ckeditor/ckeditor5-build-decoupled-document';
@Component( {
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
} )
export class AppComponent {
title = 'angular';
public Editor = DecoupledEditor;
public onReady( editor: DecoupledEditor ): void {
const element = editor.ui.getEditableElement()!;
const parent = element.parentElement!;
parent.insertBefore(
editor.ui.view.toolbar.element!,
element
);
}
}
然后,在模板中
<!-- app.component.html -->
<ckeditor [editor]="Editor" data="<p>Hello, world!</p>" (ready)="onReady($event)"></ckeditor>
# 使用自定义 CKEditor 5 构建
如果您想将更多插件添加到现有构建中,或自定义无法使用 编辑器配置 控制的内容,您需要先创建一个自定义构建,如 从源代码构建编辑器 指南中所述。
完成上述教程后,您应该会得到一个生成的 ckeditor.js
文件(以及相应的翻译文件)。在下一步中,您应该将其复制到 src
目录中,并将其导入到组件文件中。
// app.component.ts
import * as Editor from 'path/to/the/ckeditor';
@Component( {
// ...
} )
export class MyComponent {
public Editor = Editor;
// ...
}
请注意,要允许导入 JavaScript 文件而不提供其相应的类型,您需要在 tsconfig.json
文件中将 allowJs
设置为 true
。另外,确保您将目标设置为 ES6
或更高版本,否则您可能会遇到 奇怪的转译错误 在生产构建中。
// tsconfig.json
"compilerOptions": {
"allowJs": true,
"target": "es2015"
// other options
}
如果您无法将目标设置为高于 es5
,请尝试设置 "buildOptimizer": false
,这将生成一个更大的,但正确的生产构建。
# 集成在线构建器构建的版本
本指南假设您使用 CKEditor 5 在线构建器 创建了一个包含编辑器构建的 zip 存档。
将其解压缩到您的应用程序的主目录中。包含编辑器构建的目录不能放置在 src/
目录中,因为 Node 会返回错误。因此,我们建议将目录放置在 src/
和 node_modules/
文件夹旁边
├── ckeditor5
│ ├── build
│ ├── sample
│ ├── src
│ ├── ...
│ ├── package.json
│ └── webpack.config.js
├── node_modules
├── src
├── ...
└── package.json
然后,将位于 ckeditor5
目录中的包添加为项目的依赖项
npm install ./ckeditor5
现在,在您的应用程序中导入构建
// app.component.ts
import { Component } from '@angular/core';
import Editor from 'ckeditor5-custom-build/build/ckeditor';
@Component( {
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
} )
export class AppComponent {
title = 'customEditor';
public Editor = Editor;
}
# 使用带协作插件的编辑器
在 Angular 应用程序中集成 协作插件 的最简单方法是首先创建一个自定义构建,然后从 Angular 应用程序中导入它。请参见 使用自定义 CKEditor 5 构建。
# 与 ngModel
集成
该组件实现了 ControlValueAccessor
接口,并与 ngModel
配合使用。以下是如何使用它
在您的组件中创建一些模型以与编辑器共享
@Component( {
// ...
} )
export class MyComponent {
public model = {
editorData: '<p>Hello, world!</p>'
};
// ...
}
在模板中使用该模型来启用双向数据绑定
<ckeditor [(ngModel)]="model.editorData" [editor]="Editor"></ckeditor>
# 支持的 @Input
属性
CKEditor 5 的 Angular 富文本编辑器组件支持以下 @Input
属性
# editor
(必需)
Editor
提供静态 create()
方法来创建编辑器实例
<ckeditor [editor]="Editor"></ckeditor>
# config
编辑器的 配置
<ckeditor [config]="{ toolbar: [ 'heading', '|', 'bold', 'italic' ] }" ...></ckeditor>
# data
编辑器的初始数据。它可以是静态值
<ckeditor data="<p>Hello, world!</p>" ...></ckeditor>
或者共享父组件的属性
@Component( {
// ...
} )
export class MyComponent {
public editorData = '<p>Hello, world!</p>';
// ...
}
<ckeditor [data]="editorData" ...></ckeditor>
# tagName
将在其上创建富文本编辑器的 HTML 元素的标签名称。
默认标签是 <div>
。
<ckeditor tagName="textarea" ...></ckeditor>
# disabled
控制编辑器的 只读 状态
@Component( {
// ...
} )
export class MyComponent {
public isDisabled = false;
// ...
toggleDisabled() {
this.isDisabled = !this.isDisabled
}
}
<ckeditor [disabled]="isDisabled" ...></ckeditor>
<button (click)="toggleDisabled()">
{{ isDisabled ? 'Enable editor' : 'Disable editor' }}
</button>
# watchdog
ContextWatchdog
类的一个实例,它负责为多个编辑器实例提供相同的上下文,并在发生崩溃时重启整个结构。
import CKSource from 'path/to/custom/build';
const Context = CKSource.Context;
const Editor = CKSource.Editor;
const ContextWatchdog = CKSource.ContextWatchdog;
@Component( {
// ...
} )
export class MyComponent {
public editor = Editor;
public watchdog: any;
public ready = false;
ngOnInit() {
const contextConfig = {};
this.watchdog = new ContextWatchdog( Context );
this.watchdog.create( contextConfig )
.then( () => {
this.ready = true;
} );
}
}
<div *ngIf="ready">
<ckeditor [watchdog]="watchdog" ...></ckeditor>
<ckeditor [watchdog]="watchdog" ...></ckeditor>
<ckeditor [watchdog]="watchdog" ...></ckeditor>
</div>
# editorWatchdogConfig
如果未使用watchdog
属性,则默认使用EditorWatchdog
。editorWatchdogConfig
属性允许传递配置给该看门狗。
@Component( {
// ...
} )
export class MyComponent {
public myWatchdogConfig = {
crashNumberLimit: 5,
// ...
};
// ...
}
<ckeditor [editorWatchdogConfig]="myWatchdogConfig" ...></ckeditor>
# disableTwoWayDataBinding
允许禁用双向数据绑定机制。默认值为false
。
引入此选项的原因是在大型文档中存在性能问题。默认情况下,在使用ngModel
指令时,每当编辑器的数据发生变化时,组件都必须同步编辑器实例和连接属性之间的数据。这会导致调用editor.getData()
函数,这会导致在大型文档中键入时出现大规模的减速。
此选项允许集成者禁用默认行为,仅按需调用editor.getData()
方法,从而避免了减速。您可以在相关问题中阅读更多内容。
# 支持的@Output
属性
以下@Output
属性由CKEditor 5 富文本编辑器组件(适用于Angular)支持。
# ready
编辑器准备就绪时触发。它对应于editor#ready
事件。
它会与编辑器实例一起触发。
请注意,此方法可能会被多次调用。除了初始化之外,它还会在编辑器在崩溃后重新启动时被调用。不要在内部保留对编辑器实例的引用,因为它将在重新启动的情况下发生变化。相反,您应该使用watchdog.editor
属性。
# change
编辑器的内容发生变化时触发。它对应于editor.model.document#change:data
事件。
它会与包含编辑器和 CKEditor 5 change:data
事件对象的的对象一起触发。
<ckeditor [editor]="Editor" (change)="onChange($event)"></ckeditor>
import * as ClassicEditor from '@ckeditor/ckeditor5-build-classic';
import { ChangeEvent } from '@ckeditor/ckeditor5-angular/ckeditor.component';
@Component( {
// ...
} )
export class MyComponent {
public Editor = ClassicEditor;
public onChange( { editor }: ChangeEvent ) {
const data = editor.getData();
console.log( data );
}
...
}
# blur
编辑器的编辑视图失去焦点时触发。它对应于editor.editing.view.document#blur
事件。
它会与包含编辑器和 CKEditor 5 blur
事件数据的对象一起触发。
# focus
编辑器的编辑视图获得焦点时触发。它对应于editor.editing.view.document#focus
事件。
它会与包含编辑器和 CKEditor 5 focus
事件数据的对象一起触发。
# error
编辑器崩溃时触发。一旦编辑器崩溃,内部看门狗机制将重新启动编辑器并触发ready事件。
在 ckeditor5-angular v7.0.1
之前,此事件不会在编辑器初始化期间崩溃时触发。
# 样式
CKEditor 5 富文本编辑器组件(适用于Angular)可以使用组件样式表或全局样式表进行样式设置。了解如何使用这两种方法设置 CKEditor 5 组件的高度。
# 通过组件样式表设置高度
首先,在父组件的目录中创建一个 (S)CSS 文件,并使用:host
和::ng-deep
伪选择器对给定编辑器部分进行样式设置。
/* src/app/app.component.css */
:host ::ng-deep .ck-editor__editable_inline {
min-height: 500px;
}
然后,在父组件中添加对上述样式表的相对路径。
/* src/app/app.component.ts */
@Component( {
// ...
styleUrls: [ './app.component.css' ]
} )
# 通过全局样式表设置高度
要使用全局样式表对组件进行样式设置,请先创建它。
/* src/styles.css */
.ck-editor__editable_inline {
min-height: 500px;
}
然后,将其添加到angular.json
配置文件中。
"architect": {
"build": {
"options": {
"styles": [
{ "input": "src/styles.css" }
]
}
}
}
# 设置占位符
要在主可编辑元素中显示占位符,请在 CKEditor 5 富文本编辑器组件配置中设置placeholder
字段。
@Component( {
// ...
} )
export class MyComponent {
public config = {
placeholder: 'Type the content here!'
}
}
# 访问编辑器实例
CKEditor 5 富文本编辑器组件提供了满足大多数用例所需的全部功能。如果需要访问完整的 CKEditor 5 API,您可以通过一个额外的步骤获取编辑器实例。
为此,创建一个指向<ckeditor>
组件的模板引用变量#editor
。
<ckeditor #editor [editor]="Editor" ...></ckeditor>
然后使用由@ViewChild( 'editor' )
修饰的属性获取<ckeditor>
组件,并在需要时访问编辑器实例。
@Component()
export class MyComponent {
@ViewChild( 'editor' ) editorComponent: CKEditorComponent;
public getEditor() {
// Warning: This may return "undefined" if the editor is hidden behind the `*ngIf` directive or
// if the editor is not fully initialised yet.
return this.editorComponent.editorInstance;
}
}
编辑器创建是异步的,因此editorInstance
在编辑器创建之前不可用。如果您想对刚创建的编辑器进行更改,更好的选择是在ready
事件中获取 CKEditor 5 实例。
# 本地化
CKEditor 5 富文本编辑器组件可以通过两个步骤进行本地化。
# 加载翻译文件
首先,您需要将翻译文件添加到捆绑包中。此步骤可以通过两种方式实现。
通过在您的组件文件中直接导入给定语言的翻译。
import '@ckeditor/ckeditor5-build-classic/build/translations/de';
import * as ClassicEditor from '@ckeditor/ckeditor5-build-classic';
// More imports.
// ...
通过将翻译文件的路径添加到angular.json
中的"scripts"
数组中。
"architect": {
"build": {
"options": {
"scripts": [ "node_modules/@ckeditor/ckeditor5-build-classic/build/translations/de.js" ]
}
}
}
# 配置语言
然后,您需要配置编辑器以使用给定语言。
@Component( {
// ...
} )
export class MyComponent {
public Editor = ClassicEditor;
public config = {
language: 'de'
};
}
有关高级用法,请参阅设置 UI 语言指南。
# 常见问题
# zone.js
在升级到新的 Angular 版本时,zone.js 库存在一个可重复出现的错误。ngOnDestroy 处理程序会崩溃并抛出
ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'data-ck-expando' of undefined
TypeError: Cannot read property 'data-ck-expando' of undefined
解决方法:在polyfills.js
中使用import zone.js/dist/zone.js
而不是import 'zone.js'
来导入 zone.js。
更多详细信息
- https://github.com/ckeditor/ckeditor5-angular/issues/109
- https://github.com/angular/angular/tree/master/packages/zone.js#breaking-changes-since-zonejs-v0111
# 贡献和报告问题
CKEditor 5 富文本编辑器组件(适用于Angular)的源代码在 GitHub 上的https://github.com/ckeditor/ckeditor5-angular中提供。
我们每天都在努力使我们的文档保持完整。您是否发现过时信息?是否有遗漏内容?请通过我们的问题跟踪器报告。
随着 42.0.0 版的发布,我们重新编写了大部分文档以反映新的导入路径和功能。我们感谢您的反馈,帮助我们确保文档的准确性和完整性。