敲碎时间,铸造不朽的个人专栏
上一篇

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中的一些值。

 

 

 

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