这是我自己在 RC6 上使用的。首先我将展示用法:
<h1>The Editor</h1>
<textarea htmlEditor [(ngModel)]="txt"></textarea>
<h1>The HTML Source</h1>
<textarea [(ngModel)]="txt"></textarea>
<h1>The Rendered HTML</h1>
<div [innerHTML]="txt"></div>
所以用法非常简单直接,编辑器的HTML结果移动到textarea的值(我在blur事件上触发更新)
这是指令定义(Typescript):
import {
Directive,
OnDestroy,
AfterViewInit,
Provider,
forwardRef,
HostBinding
} from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
import { DomSanitizer } from '@angular/platform-browser';
declare var tinymce: any;
export const TinyMceValueAccessor: Provider = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => TinyMceDirective2),
multi: true
};
// Tinymce directive
@Directive({
selector: '[htmlEditor]',
providers: [TinyMceValueAccessor]
})
export class TinyMceDirective2 implements OnDestroy, AfterViewInit, ControlValueAccessor {
static nextUniqueId = 0;
@HostBinding('attr.data-tinymce-uniqueid') uniqueId;
onTouchedCallback: () => void = () => { };
onChangeCallback: (_: any) => void = () => { };
innerValue;
init = false;
constructor(private sanitizer: DomSanitizer) {
this.uniqueId = `tinymce-host-${TinyMceDirective2.nextUniqueId++}`;
}
//get accessor
get value(): any {
return this.innerValue;
};
//set accessor including call the onchange callback
set value(v: any) {
if (v !== this.innerValue) {
this.innerValue = v;
this.onChangeCallback(v);
}
}
ngAfterViewInit(): void {
console.log('tinymce');
tinymce.init({
selector: `[data-tinymce-uniqueid=${this.uniqueId}]`,
schema: 'html5',
setup: ed => {
ed.on('init', ed2 => {
if (this.innerValue) ed2.target.setContent(this.innerValue);
this.init = true;
});
}
});
// I chose to send an update on blur, you may choose otherwise
tinymce.activeEditor.on('blur', () => this.updateValue());
}
updateValue() {
const content = tinymce.activeEditor.getContent();
this.value = this.sanitizer.bypassSecurityTrustHtml(content);
}
writeValue(value): void {
if (value !== this.innerValue) {
this.innerValue = value;
if (this.init && value) tinymce.activeEditor.setContent(value);
}
}
registerOnChange(fn): void {
this.onChangeCallback = fn;
}
registerOnTouched(fn): void {
this.onTouchedCallback = fn;
}
ngOnDestroy(): void {
if (this.init) tinymce.remove(`[data-tinymce-uniqueid=${this.uniqueId}]`);
}
}
一些亮点:
- 我正在使用
NG_VALUE_ACCESSOR 提供使用ngModel 的双向绑定
- 我正在为宿主元素上的自定义属性分配一个唯一的 ID,以便 tinymce 仅初始化该特定元素而不会初始化其他元素。
- 我仅在
blur 事件上发送值更新,但您可以使用不同的策略,例如使用去抖动时间。
- 我使用
DomSanitizer 绕过清理,因为tinymce 有时会输出触发Angular 2 清理的html。