tinymce / tinymce-angular

Official TinyMCE Angular Component
MIT License
324 stars 93 forks source link

ValueChanges should not emit when editor is initialized if value did not change #178

Closed jgbpercy closed 3 years ago

jgbpercy commented 4 years ago

What is the current behavior?

Currently, the valueChanges Observable for a reactive forms FormControl bound to a tiny mce editor will emit when the tiny mce editor inits, even if the value in the control did not change. I can see why valueChanges emits here, as initializing the editor may add markup that changes the value (e.g. "Hello" turns into "<p>Hello</p>"). However, for me this is not desirable behavior if the value passed in already contains markup and isn't changed by the editor initializing (e.g. if the FormControl already has the value "<p>Hello</p>").

See this minimal repro on stackblitz - note that "<p>Hi</p>" is logged to the console twice.

What is the expected behavior?

"<p>Hi</p>" is logged to the console once.

Which versions of TinyMCE/TinyMCE-Angular, and which browser / OS are affected by this issue? Did this work in previous versions of TinyMCE or TinyMCE-Angular?

This is using v4.0.0. I haven't used previous version of the official Angular component - in the past I've rolled my own wrapper element with tinymce core 4.x, but I decided to try this component rather than update my wrapper to use 5.x.

Other notes

There seems to be a fairly simple fix for this: within the initEditor method, before calling this.onChangeCallback, check if this.initialValue is equal to editor.getContent({ format: this.outputFormat }), and don't call onChangeCallback if they are equal.

That said, I can see that this is technically a breaking change, but would be more than happy if the above behavior is optional (e.g. there is a new emitValueChangeOnInitIfEqual angular @Input which defaults to true, and does the check suggested above if false is passed).

blovell33 commented 4 years ago

This is likely the issue that is affecting me as well.

Seems like this example...

<editor [(ngModel)]="model.foo" [init]="init()" name="foo"></editor>

...is always setting the ngModel state to dirty even when on init the form should be in a pristine state until changes in the editor are made. I'm having to set init_instance_callback to use a function that sets the form to pristine after the editor is loaded. This sort of works, however the user can also type into the editor before the ngModel binding takes place and this is randomly throwing errors in our app when a user does this.

The behavior should be that when a form is loaded it is still in a pristine state after the initial editor ngModel binding. Everything that I'm seeing would suggest otherwise.

jacknkandy commented 4 years ago

I was using (ngModelChange) and noticed this same issue was occurring for me after upgrading to the latest release (to coincide with updating my app to Angular 10).

jscasca commented 4 years ago

We are looking into this. Ideally if the content is the same after initliazing TinyMCE the wrapper shouldn't emit a change event. However, if the content changes due to the editor internal processes it will trigger a change event.

jscasca commented 3 years ago

So this should be the default behaviour in 4.2.0. No reason to trigger a change event if the value didn't change on initialization of the editor.

benshabatnoam commented 2 years ago

What should I do if I'm using v3.x and I can't upgrade?