我正在使用一个可编辑内容的div在Angular中构建自己的自定义WYSIWYG文本编辑器。我将它提取为一个组件。我希望能够键入一些文本并对其进行格式化,然后当我从父组件中点击一个按钮时,它应该改变编辑器中的文本或更新它。
我的父组件看起来如下。
@Component({
selector: 'app-parent',
templateUrl: `
<form [formGroup]="form">
<app-default-editor
formControlName="body" >
</app-default-editor>
</form>
<button (click)="changeValue()">Change Value</button>
<p *ngIf="!form.valid">Counter is invalid!</p>
<pre>{{ form.value | json }}</pre>
`
})
export class ParentComponent {
initialText = '<H1>This is the heading</H1>';
form = this.fb.group({
body: '<H1>This is the heading</H1>'
});
changeValue(){
this.form.patchValue({ body: 'This is my new text' });
}
}
我的编辑器组件看起来是这样的
@Component({
selector: 'app-parent',
templateUrl: `
<button (click)="executeCommand('bold')" ><i class="fas fa-bold"></i></button>
<button (click)="executeCommand('italic')" ><i class="fas fa-italic"></i></button>
<button (click)="executeCommand('underline')" ><i class="fas fa-underline"></i></button>
<div
#htmlEditor
id="htmlEditor"
contenteditable="true"
(input)="onTextChanged()"
[innerHTML]="initialText">
</div>
`
})
export class EditorComponent implements ControlValueAccessor, OnChanges {
@Input()
initialText = "";
@Input()
_textValue = "";
@Input()
minValue = 0;
@ViewChild('htmlEditor') htmlEditor;
ngAfterViewInit() {
this.htmlEditor.nativeElement.innerHTML = this.initialText;
}
get textValue() {
return this._textValue;
}
set textValue(val) {
this._textValue = val;
this.propagateChange(this._textValue);
}
writeValue(value: any) {
if (value !== undefined) {
this.textValue = value;
}
}
propagateChange = (_: any) => { };
registerOnChange(fn) {
this.propagateChange = fn;
}
registerOnTouched() { }
validateFn: Function;
ngOnChanges(changes) {
this.validateFn = createEditorRequiredValidator();
}
onTextChanged() {
this.textValue = this.htmlEditor.nativeElement.innerHTML;
}
executeCommand(cmd) {
document.execCommand(cmd, false, this.htmlEditor.nativeElement);
}
}
export function createEditorRequiredValidator() {
return function validateEditor(c: FormControl) {
let err = {
requiredError: {
given: c.value,
required: true
}
};
return (c.value.length == 0) ? err : null;
}
}
使用当前的代码,我可以将文本格式化为粗体、斜体等,而父组件中的表单可以显示标签中的值。当我点击按钮将文本改为预定义的值时,表单会更新,但编辑器不显示任何变化。
我最后把父组件中的changeValue方法改成了。
changeValue(){
this.form.patchValue({ body: [WHATEVER THE TEXT MUST BE] });
this.initialText = [WHATEVER THE TEXT MUST BE]
}
这似乎是可行的,但我不认为这是最好的答案。