From dde33ea79e7842732d3f5e3248052032ec7d1193 Mon Sep 17 00:00:00 2001 From: Maciej Bukowski Date: Fri, 4 Oct 2019 12:32:58 +0200 Subject: [PATCH] Prevented ckeditor component from calling CVA onChange when the change comes from the CVA. --- src/app/demo-form/demo-form.component.spec.ts | 2 +- .../demo-reactive-form.component.spec.ts | 2 +- src/ckeditor/ckeditor.component.spec.ts | 13 +++++++++++++ src/ckeditor/ckeditor.component.ts | 11 ++++++++++- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/app/demo-form/demo-form.component.spec.ts b/src/app/demo-form/demo-form.component.spec.ts index faaae3e..0328e5e 100644 --- a/src/app/demo-form/demo-form.component.spec.ts +++ b/src/app/demo-form/demo-form.component.spec.ts @@ -55,7 +55,7 @@ describe( 'DemoFormComponent', () => { fixture.detectChanges(); - expect( component.formDataPreview ).toEqual( '{"name":null,"surname":null,"description":""}' ); + expect( component.formDataPreview ).toEqual( '{"name":null,"surname":null,"description":null}' ); done(); } ); diff --git a/src/app/demo-reactive-form/demo-reactive-form.component.spec.ts b/src/app/demo-reactive-form/demo-reactive-form.component.spec.ts index 36b121e..24752da 100644 --- a/src/app/demo-reactive-form/demo-reactive-form.component.spec.ts +++ b/src/app/demo-reactive-form/demo-reactive-form.component.spec.ts @@ -55,7 +55,7 @@ describe( 'DemoReactiveFormComponent', () => { fixture.detectChanges(); - expect( component.formDataPreview ).toEqual( '{"name":null,"surname":null,"description":""}' ); + expect( component.formDataPreview ).toEqual( '{"name":null,"surname":null,"description":null}' ); done(); } ); diff --git a/src/ckeditor/ckeditor.component.spec.ts b/src/ckeditor/ckeditor.component.spec.ts index 77fc424..de3b18d 100644 --- a/src/ckeditor/ckeditor.component.spec.ts +++ b/src/ckeditor/ckeditor.component.spec.ts @@ -285,6 +285,19 @@ describe( 'CKEditorComponent', () => { expect( spy ).toHaveBeenCalledWith( '

foo

' ); } ); } ); + + it( 'onChange callback should not be called when the change is coming from outside of the editor', () => { + fixture.detectChanges(); + + return wait().then( () => { + const spy = jasmine.createSpy(); + component.registerOnChange( spy ); + + component.writeValue( 'foo' ); + + expect( spy ).not.toHaveBeenCalled(); + } ); + } ); } ); } ); diff --git a/src/ckeditor/ckeditor.component.ts b/src/ckeditor/ckeditor.component.ts index 4e3ca3c..73cc487 100644 --- a/src/ckeditor/ckeditor.component.ts +++ b/src/ckeditor/ckeditor.component.ts @@ -150,6 +150,11 @@ export class CKEditorComponent implements AfterViewInit, OnDestroy, ControlValue */ private editorElement?: HTMLElement; + /** + * A lock flag preventing from calling the `cvaOnChange()` during setting editor data. + */ + private isEditorSettingData = false; + public constructor( elementRef: ElementRef, ngZone: NgZone ) { this.ngZone = ngZone; this.elementRef = elementRef; @@ -180,7 +185,11 @@ export class CKEditorComponent implements AfterViewInit, OnDestroy, ControlValue // If already initialized. if ( this.editorInstance ) { + // The lock mechanism prevents from calling `cvaOnChange()` during changing + // the editor state. See #139 + this.isEditorSettingData = true; this.editorInstance.setData( value ); + this.isEditorSettingData = false; } // If not, wait for it to be ready; store the data. else { @@ -265,7 +274,7 @@ export class CKEditorComponent implements AfterViewInit, OnDestroy, ControlValue modelDocument.on( 'change:data', ( evt: CKEditor5.EventInfo<'change:data'> ) => { this.ngZone.run( () => { - if ( this.cvaOnChange ) { + if ( this.cvaOnChange && !this.isEditorSettingData ) { const data = editor.getData(); this.cvaOnChange( data );