CKEditor5事件系统源码分析(三)

选中文字可对指定文章内容进行评论啦,→和←可快速切换按钮,绿色背景文字可以点击查看评论额。

CKEditor5事件系统源码分析(三)

上一节我们分析了事件系统的关键类EmitterMixin的fire()方法,今天我们看看另一个方法就是delegate()

这个方法的代码如下:

delegate( ...events ) {
	return {
		to: ( emitter, nameOrFunction ) => {
			if ( !this._delegations ) {
				this._delegations = new Map();
			}

		    // Originally there was a for..of loop which unfortunately caused an error in Babel that didn't allow
			// build an application. See: https://github.com/ckeditor/ckeditor5-react/issues/40.
			events.forEach( eventName => {
				const destinations = this._delegations.get( eventName );

				if ( !destinations ) {
					this._delegations.set( eventName, new Map( [ [ emitter, nameOrFunction ] ] ) );
				} else {
					destinations.set( emitter, nameOrFunction );
				}
			} );
		}
	};
}

这个方法就比较简单,首先,我们需要一个代理映射,这个代理映射是一个map,它的key显然是事件名称,而value值又是一个map,这个map的key是emitter,value是事件名称或者一个函数。

实际上在调用这个delegate方法的时候,本质上就是存储一些数据结构,而这个结构是有一个两层的map来构建的。

这样在fire的时候,先取出这些map,然后再调用一个方法就是fireDelegatedEvents

下面我们看看这个方法:

fireDelegatedEvents( destinations, eventInfo, fireArgs ) {
	for ( let [ emitter, name ] of destinations ) {
		if ( !name ) {
			name = eventInfo.name;
		} else if ( typeof name == 'function' ) {
			name = name( eventInfo.name );
		}

		const delegatedInfo = new EventInfo( eventInfo.source, name );

		delegatedInfo.path = [ ...eventInfo.path ];

		emitter.fire( delegatedInfo, ...fireArgs );
	}
}

首先会跌倒这个事件对应的map,实际上就是一个一个的<emitter,name>对,然后构造具体的事件,这个通过代码const delegatedInfo = new EventInfo( eventInfo.source, name );,然后配置path,最后调用fire出发事件,迭代完map实际上就是执行所有的代理功能。

好了,这个方法挺简单的,至于取消代理的方法就不用分析了,本质上就是删除两层map中的一些值。

 

 

 

版权声明:著作权归作者所有。

相关推荐

Android dex文件反编译为Java源码

工具准备 dex2jar:国人写的一个dex反编译为java的工具jd-gui:查看java源码的gui工具反编译步骤步骤一把test_apk-debug.apk里的classes.dex转换为test_apk-debug_dex2jar.jard2j-dex2jar.sh -f -o output_jar.jar apk_to_decompile.apk

Java源码分析:产生随机数Random与ThreadLocalRandom的区别

Java用于产生随机数的方法主要有两种:java.util.Random和java.util.concurrent.ThreadLocalRandom。Random从Jdk 1.0开始就有了,而ThreadLocalRandom是Jdk1.7才新增的。简单从命名和类所在的包上看,两者的区别在于对并发的支持。RandomRandom是一个伪随机数生成器,它内置了一个种子数seed。获取随机

Rxjs expand的用法分析

Rxjs的expand()函数声明:public expand(project: function(value: T, index: number), concurrent: number, scheduler: Scheduler): Observable expand()会递归调用project函数,project函数把源值映射为一个Observable,每次递归

雪花算法实现-分布式系统

一、订单id的特殊性订单数据非常庞大,将来一定会做分库分表。那么这种情况下, 要保证id的唯一,就不能靠数据库自增,而是自己来实现算法,生成唯一id。二、雪花算法这里的订单id是通过一个工具类生成的,而工具类所采用的生成id算法,是由Twitter公司开源的snowflake(雪花)算法。三、简单原理雪花算法会生成一个64位的二进制数据,为一个Long型。(转换成字符串后长度最多19位) ,其基本

Linux查看及修改系统的资源限制命令ulimit

在Linux,查看系统对资源使用的显示可以使用命令ulimit,其中参数-a会列出所有的资源使用限制。[demo@server ~]$ ulimit -acore file size (blocks, -c) 0data seg size (kbytes, -d) unlimitedscheduling priority (-e) 0f

JIT的分层编译和逃逸分析

JIT到底在Java的运行中发挥了什么作用呢?根据查阅到的资料,一个作用是做分层编译,一个是做对象的逃逸分析。对于循环体中的代码,循环到一定的程度的时候,就会被再次被编译,编程执行速度更加迅速的代码。对于新建的对象,讲过逃逸分析,如果数据不会逃逸,则将数据放在栈上,不再在heap上新建这个对象。这样的好处是:避免了在堆上新建的锁堆导致的资源损耗不需要GC

CKEditor5事件系统(基础使用)

最近在学习CK5,一种最大的感受就是CK5的架构不是很大,但是内容特别多。笔者在学习中,总结出一个浅显的道理,那就是掌握基础知识,对框架宏观把握,学习起来会事半功倍。今天开始初步研究一下CK5的事件系统:在CK5的事件系统中,关键的一个对象被称作Emitter(发射器),Emitter是一个可以发送事件的对象。如何创建一个Emitter,下面的代码创建了一个混合了事件发送的AnyClass类,它实

CKEditor5事件系统(事件优先级)

今天继续学习CK5的事件系统,上一节我们知道了绑定和取消绑定事件的两种方法,知道在一个emitter上一个同名事件可以绑定多个回调函数,自然问题来了,这些函数的执行顺序是怎么样的呢?CK5的事件监听优先级实际上,对于一个同名事件,CK5提供了事件优先级功能,如下代码所示const anyClass = new AnyClass(); anyClass.on( 'eventName', ( even

CKEditor5事件系统(代理事件)

emitter接口提供了事件代理机制。也就是说指定选择的事件能够被其他的emitter触发。 1、代理指定的事件到另一个emitterlet anyClass = new AnyClass(); let anotherClass = new AnyClass(); let oneClass = new AnyClass(); anotherClass.on('bar',(evt,data

CKEditor5——模型理解(三:Element Text)

在上一节,我们学习了CK5中模型节点Node的API,今天我们学习另一个常用的API:Element。元素节点说明element表示模型的元素节点类型,它包含一个拥有名称和子节点的节点类型,继承自Node类。元素属性说明1、name,元素的名称举个例子哈,段落的名称是paragraph,代码块的名称是codeBlock等等。2、childCount, 子元素的数目这里指的是此元素节点包含的子元素的