Search code examples
angularckeditorangular7angular8ckeditor5

CKEditor 5 - Angular 7 : object ngModel binding with sub childs problem


1- First here is my codes:


ListPagesComponent:

export class ListPagesComponent {
    public model = {
            id: -1,
            actif: 0,
            link: '',
            htmlContent: {
                fr: '',
                en: ''
            },
            title: {
                fr: '',
                en: ''
            }
        };    
    updatePage() {
                this.model = {
                    id: -1,
                    actif: 0,
                    link: 'my-link',
                    htmlContent: {
                        fr: 'Salut tout le monde',
                        en: 'hello welcome'
                    },
                    title: {
                        fr: 'title1',
                        en: 'title2'
                    }
                };
                console.log(this.model);
            }
}

listpages.component.html - CKeditors in the same page:

 <ckeditor name="content" 
    [editor]="editor1" 
    data=" " 
    (ready)="onReady($event) 
    [config]="editorConfig" 
    [(ngModel)]="model.htmlContent[langs.fr]">
    </ckeditor>

<ckeditor name="content" 
[editor]="editor1" 
data=" " 
(ready)="onReady($event)" 
[config]="editorConfig" 
[(ngModel)]="model.htmlContent[langs.en]">
</ckeditor>

2- explanation of the issue: when I click on a button who perform the execution of updatePage() , I expect to have as a result in the console : the correct new values of the updated htmlContents of frensh and english langages like :

actif: 0
htmlContent:
en: "<p>hello welcome</p>"
fr: "<p>Salut tout le mond</p>" <==== THE Expected Result
id: -1
link: "my-link"
title: {fr: "title1", en: "title2"}

the problem is that the given result is:

actif: 0
htmlContent:
en: "<p>hello welcome</p>"
fr: "<p>hello welcome</p>"   <==== THE ISSUE IS HERE 
id: -1
link: "my-link"
title: {fr: "title1", en: "title2"}

I hope my issue is clear.


Solution

  • I fixed my issue : to be honest, I'm not sure if it is a CKEditor5 Multi-instances cycle life bug or not , but to resolve the problem, I just created a new component for reuse wich contains one instance of CKEditor component, and i passed to it an Input/output string property to make differences between different langages content (FR, EN etc..), and I just used this component in the parent wich contains the modal with the editor.. so this is my code solution :


    the new added HTMLEditorComponent :

    export class HTMLEditorComponent implements OnInit {
        /** Global Props **/
        public editor1 = DecoupledEditor;
        @Input() content: string;
        @Output() contentChange: EventEmitter<string> = new EventEmitter();
    
        langs = {
            fr: 'fr',
            en: 'en',
        };
        /** editor configuration **/
        public editorConfig = {
            placeholder: 'Ecrire votre contenu ici!',
        };
    
        constructor() {
        }
    
        ngOnInit() {
        }
    
        /**
         * Init Global Page Editor
         * @param editor
         */
        public onReady(editor) {
            this.initEditor(editor);
        }
    
        /**
         * Init editor ui & toolbar
         * @param editor
         */
        private initEditor(editor) {
            editor.ui.getEditableElement().parentElement.insertBefore(
                editor.ui.view.toolbar.element,
                editor.ui.getEditableElement(),
            );
        }
    
        /**
         * Update out changes
         */
        onChange() {
            console.log(this.content);
            this.contentChange.emit(this.content);
        }
    

    its view htmleditor.component.html:

    <ckeditor name="content"
              [editor]="editor1" data=" " (ready)="onReady($event)"
              [(ngModel)]="content"
              [config]="editorConfig"
              (ngModelChange)="onChange()"
    ></ckeditor>
    

    the parent component ListPagesComponent :

    export class ListPagesComponent implements OnInit {
    
    // other codes here ...
    
    /** List of available extensible langages **/
        langs = {
            fr: 'fr',
            en: 'en',
        };
    /** Page Editor props **/
        page: Page = new Page();
        selectedLanguage: string = this.langs.fr;
    
    // other codes here ...
    // other codes here ...
    /**
         * Modifier Page
         */
        updatePage() {
            this.showAddModal();
            //  update request
        }
    // other codes here ..
    // other codes here ..
    }
    

    and this is how I used my HtmlEditorComponent in the parent ListPagesComponent html view:

    // for frensh language
    <app-htmleditor [(content)]="page.htmlContent[langs.fr]"></app-htmleditor>
    // for English language
    <app-htmleditor [(content)]="page.htmlContent[langs.en]"></app-htmleditor>
    

    I hope my solution is good for whose uses CKeditor5 :).