CKEditor5事件系统(基础使用)

时间:2023-05-12 17:42:27

最近在学习CK5,一种最大的感受就是CK5的架构不是很大,但是内容特别多。笔者在学习中,总结出一个浅显的薄理,那就是如果掌握了基础知识,再加上宏观上的把握,学习起来会事半功倍。

 

今天开始研究一下CK5的事件系统:

emitters是一个可以发送事件的对象。

import EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';
import mix from '@ckeditor/ckeditor5-utils/src/mix';
class AnyClass {
   // ...
}
mix( AnyClass, EmitterMixin );

上面的代码来自CK5的官网,分析以上代码,可以看出核心的类有两个,一个是EmitterMixin,另一个是mix。

不难看出,第一个是实现了事件系统的核心类,而mix方法只是将核心功能复制到具体类。

Emitter的On和Off分析

有了以上代码后AnyClass就是一个具有监听和发送时间的类,因此可以有以下代码:

AnyClass.on( 'eventName', ( eventInfo, ...args ) => { ... } );

这个AnyClass类就可以监听一个名为eventName的事件,一旦触发这个事件,那么就会执行后面的回调函数。

再次用另一段代码来说明问题

splitButtonView.on( 'execute', () => {
	editor.execute( 'newCodeBlock', {
		usePreviousLanguageChoice: true
	} );
	editor.editing.view.focus();
} );

看到了吧,这段代码的意思是,一旦在splitButtonView触发execute事件,那么就会执行回调函数。这里需要注意的是:

  1. splitButtonView是一个emitter对象
  2. 触发事件只能在这个splitButtonView对象上,也就是自己监听自己

如果要移除监听呢?

AnyClass.off( 'eventName', handler );

简单吧。

Emitter的listenTo和stopListening分析

CK5还提供了另一种监听方式:

AnyClass.listenTo( AnotherClass, 'eventName', ( eventInfo, ...args ) => { ... } );

这里的意思就是emitter:AnyClass 监听 emitter:AnotherClass上的eventName事件,如果后者触发了这个事件,那么回到函数会理解执行。

this.listenTo( editor.editing.view.document, 'clipboardInput', ( evt, data ) => {
    console.log('clipboardInput');
    let insertionRange = model.createRange( model.document.selection.anchor );
 
    // Use target ranges in case this is a drop.
    if ( data.targetRanges ) {
          insertionRange = editor.editing.mapper.toModelRange( data.targetRanges[ 0 ] );
    }
 
    if ( !insertionRange.start.parent.is( 'element', 'newCodeBlock' ) ) {
          return;
    }
 
    const text = data.dataTransfer.getData( 'text/plain' );
    const writer = new UpcastWriter( editor.editing.view.document );
 
    // Pass the view fragment to the default clipboardInput handler.
    data.content = rawSnippetTextToViewDocumentFragment( writer, text );
} );

上面的代码我是从一个插件类中摘取出来的,this就代表这个插件类,而这个插件类会监听这个对象:

editor.editing.view .document

而监听的事件是剪贴板在视图文档的输入,其实说人话就是当我们复制一些内容到CK5的内容去的时候,这个插件的回调函数就会执行。

同样的道理,如果想移除对某个emitter的监听:

// Stop listening to a specific handler.
AnyClass.stopListening( AnotherClass, 'eventName', handler );
// Stop listening to a specific event.
AnyClass.stopListening( AnotherClass, 'eventName' );
// Stop listening to all events fired by a specific emitter.
AnyClass.stopListening( AnotherClass);
// Stop listening to all events fired by all bound emitters.
AnyClass.stopListening();

进过这些介绍,我想大家应该明白emitter的on和listenTo方法的区别和怎么使用了吧。