I\'m trying to embed tinymce into my website which is built using Angular2. Following is my component:
export class myComponent implements
Here's what I've used for myself, on RC6. First I'll show the usage:
The Editor
The HTML Source
The Rendered HTML
So the usage is pretty simple and straightforward, the HTML result of the editor is moved to the value of the textarea
(I trigger the update on blur
event)
And here's the directive definition (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}]`);
}
}
Some highlights:
NG_VALUE_ACCESSOR
to provide for two way binding using ngModel
blur
events, but you may use a different strategy, for example using debounce time.DomSanitizer
to bypass sanitization, since tinymce sometimes outputs html which triggers Angular 2 sanitization.