jodit / jodit-angular

Angular wrapper for Jodit && Hey. Due to the fact that I do not use Angular in my projects, I cannot fix plugin errors in a timely manner. If you want the plugin to develop, send PR or better become a contributor
MIT License
48 stars 35 forks source link

App running slow when using component #29

Open Ozmercer opened 5 years ago

Ozmercer commented 5 years ago

After adding the jodit component to the html and code, it makes my whole page run slow. If I type quickly in the editor or in an unrelated input field, I get lag of the input. It seems as though the component has a bug.

katan commented 5 years ago

The problem is how the module creates the Jodit editor instance. I've created a pull request to solve it #26 .

Meanwhile, you can create a workaround like this:

import { Component, AfterViewInit, ElementRef, forwardRef, OnDestroy, NgZone, Input } from '@angular/core';
import {
    ControlValueAccessor,
    NG_VALUE_ACCESSOR
} from '@angular/forms';
// html editor
import * as Editor from 'jodit/build/jodit.min';

@Component({
    selector: 'app-html-editor',
    template: '<ng-template></ng-template>',
    styleUrls: ['./html-editor.component.scss'],
    // Integration with @angular/forms.
    providers: [
        {
            provide: NG_VALUE_ACCESSOR,
            useExisting: forwardRef(() => HtmlEditorComponent),
            multi: true,
        }
    ]
})
export class HtmlEditorComponent implements AfterViewInit, OnDestroy, ControlValueAccessor {
    public editorInstance: any;
    private data: string;
    private textArea: Element;

    @Input('config') config: any;

    /**
     * A callback executed when the content of the editor changes. Part of the
     * `ControlValueAccessor` (https://angular.io/api/forms/ControlValueAccessor) interface.
     *
     * Note: Unset unless the component uses the `ngModel`.
     */
    private cvaOnChange?: (data: string) => void;

    /**
     * A callback executed when the editor has been blurred. Part of the
     * `ControlValueAccessor` (https://angular.io/api/forms/ControlValueAccessor) interface.
     *
     * Note: Unset unless the component uses the `ngModel`.
     */
    private cvaOnTouched?: () => void;

    constructor(private ngZone: NgZone, private elementRef: ElementRef) { }

    ngAfterViewInit() {
        this.ngZone.runOutsideAngular(() => {
            this.createEditor();
        });
    }

    // Implementing the OnDestroy interface.
    ngOnDestroy() {
        if (this.editorInstance) {
            this.editorInstance.destruct();
            this.editorInstance = null;
        }
    }

    // Implementing the ControlValueAccessor interface (only when binding to ngModel).
    writeValue(value: string | null): void {
        // This method is called with the `null` value when the form resets.
        // A component's responsibility is to restore to the initial state.
        if (value === null) {
            value = '';
        }

        // If already initialized.
        if (this.editorInstance) {
            this.editorInstance.value = value;
        }
        // If not, wait for it to be ready; store the data.
        else {
            this.data = value;
        }
    }

    // Implementing the ControlValueAccessor interface (only when binding to ngModel).
    registerOnChange(callback: (data: string) => void): void {
        this.cvaOnChange = callback;
    }

    // Implementing the ControlValueAccessor interface (only when binding to ngModel).
    registerOnTouched(callback: () => void): void {
        this.cvaOnTouched = callback;
    }

    // Implementing the ControlValueAccessor interface (only when binding to ngModel).
    setDisabledState(isDisabled: boolean): void {
        // If already initialized
        if (this.editorInstance) {
            this.editorInstance.setReadOnly(isDisabled);
        }
    }

    private createEditor() {
        this.createElement();

        if (!this.editorInstance) {
            this.editorInstance = new Editor.Jodit(this.textArea, this.config);
            // Add events
            this.addEvents();
            // Set value data
            this.editorInstance.value = this.data;
            // Resize after value adds
            this.editorInstance.events.fire('resize');
        }
    }

    private createElement() {
        if (!this.textArea) {
            this.textArea = document.createElement('textarea');
            this.elementRef.nativeElement.appendChild(this.textArea);
        }
    }

    private addEvents() {
        // data binding to ngModel on Change value
        this.editorInstance.events.on('change', (new_value: string) => {
            if (this.cvaOnChange) {
                this.cvaOnChange(new_value);
            }
        });

        // data binding to ngModel on Change value
        this.editorInstance.events.on('blur', () => {
            this.ngZone.run(() => {
                if (this.cvaOnTouched) {
                    this.cvaOnTouched();
                }
            });
        });
    }
}
dsanthosh411 commented 4 years ago

@katan still my project slow