Listen to event fired when the content has changed

2020-08-18 15:35发布

问题:

How can I listen to the "input" event in ckeditor5 ? I would like to be able to use Observables like this:

Observable.fromEvent(this.editor, "input").debounceTime(250).subscribe(() => {});

So far, I've been able to listen to some events like this:

Observable.fromEvent(this.editor.editing.view, 'selectionChangeDone').subscribe(() => { });

But I don't find the name of the event that would be fired as soon as data changed in the editor. I tried "change" but it only fires when the editor get or lost focus.

回答1:

Since CKEditor5 v11.0.0 (since 21 July 2018)

What you probably need is the Document#change:data event fired by editor's document.

editor.model.document.on( 'change:data', () => {
    console.log( 'The data has changed!' );
} );

This event is fired when the document changes in such a way which is "visible" in the editor data. There's also a group of changes, like selection position changes, marker changes which do not affect the result of editor.getData(). To listen to all these changes, you can use a wider Document#change event:

editor.model.document.on( 'change', () => {
    console.log( 'The Document has changed!' );
} );

Prior to CKEditor5 v11.0.0

What you probably need is a change event fired by editor's document.

editor.model.document.on( 'change', () => {
    console.log( 'The Document has changed!' );
} );

As the documentation of this event says:

Fired after each enqueueChange() block or the outermost change() block was executed and the document was changed during that block's execution.

The changes which this event will cover include:

  • document structure changes,
  • selection changes,
  • marker changes.

If you want to be notified about all these changes, then simply listen to this event like this:

  model.document.on( 'change', () => {
      console.log( 'The Document has changed!' );
  } );

If, however, you only want to be notified about structure changes, then check whether the differ contains any changes:

  model.document.on( 'change', () => {
      if ( model.document.differ.getChanges().length > 0 ) {
          console.log( 'The Document has changed!' );
      }
  } );

The last code snippet is useful when implementing features like auto-save.



回答2:

First of all, I see you are using Observable.fromEvent which seems to be a part of RxJS and works with jQuery events. CKEditor 5 does not use RxJS nor jQuery. It uses custom events and custom observables which are something different than observable you want to use.

So note that:

Observable.fromEvent(this.editor.editing.view, 'selectionChangeDone');

is not a proper way of listening to the event and works most probably only because of some duck typing.

The proper way of listening on CKE5 events is:

this.editor.editing.view.on( 'selectionChangeDone', () => { /*...*/ } );

Second, 'input' is not an event but a command. If you want to listen in this command execution you can do:

this.editor.commands.get( 'input' ).on( 'execute', ( evt, args ) => {
    console.log( evt, args );
} );

However, this is a very fresh API, which will be introduced in the next version of ckeditor-core (0.9.0), so you need to use the current master branch to use it.