前置:
ckeditor5/utils:emittermixin(事件监听机制)
ckeditor5官网observables讲解
ckeditor5/utils:ObservableMixin
可观察的对象(Observables)是CKEditor 5 Framework的常见组成要素。
绑定到可观察对象的模板使得用户界面具有动态和交互式特质。一些基本类如Editor、Command可也是可观察对象。
- 如何设置类为observable
通过混入ObservableMixin,可以使任何类变成observable,如View基类;关于ObservableMixin,详见ckeditor5/utils:ObservableMixin。 -
set:如何设置单个属性为observable
通过从View基类获得set得方法设置属性为observable,如buttonview。
export default class ButtonView extends View {
constructor( locale ) {
super( locale );
// ......
this.set( isEnabled , true );
this.set( isOn , false );
this.set( label );
this.set( isVisible , true );
this.set( isToggleable , false );
// ......
}
}
如下代码,每当label属性改变后,change:label事件会被触发,相应的回调函数会被执行:
const view = new ButtonView();
view.on( change:label , ( evt, propertyName, newValue, oldValue ) => {
console.log(
`#${ propertyName } has changed from "${ oldValue }" to "${ newValue }"`
);
} )
view.label = Hello world! ; // -> #label has changed from "undefined" to "Hello world!"
view.label = Bold ; // -> #label has changed from "Hello world!" to "Bold"
view.type = submit ; // Changing a regular property fires no event.
-
delegate:除了set方法外,还有其他方法如delegate等也可以用于设置属性为observable:
buttonFoo.delegate( execute ).to( toolbar );
buttonBar.delegate( execute ).to( toolbar );
toolbar.on( execute , evt => {
console.log( `The "${ evt.source.label }" button was clicked!` );
} );
-
bind:
// editor.commands.isEnabled必须使用set方法定义,才能保证bind方法的有效性
const button = new Button();
const command = editor.commands.get( bold );
button.bind( isEnabled ).to( command, isEnabled );
- decorate(装饰):
通过decorate方法,可以将object methods转换为事件驱动性质的方法。当某个方法被decorate后,那么当方法被执行时,一个同名的事件将会被创建和触发。源码很简单,如下:
decorate( methodName ) {
const originalMethod = this[ methodName ];
if ( !originalMethod ) {
throw new CKEditorError(
observablemixin-cannot-decorate-undefined ,
this,
{ object: this, methodName }
);
}
this.on( methodName, ( evt, args ) => {
evt.return = originalMethod.apply( this, args );
} );
this[ methodName ] = function( ...args ) {
return this.fire( methodName, args );
};
}
实例如下:
class Button extends View {
constructor() {
// ...
this.decorate( focus ); // 注意这里!!!
}
focus( force ) {
console.log( `Focusing button, force argument="${ force }"` );
// Unless forced, the button will only focus when not already focused.
if ( force || document.activeElement != this.element ) {
this.element.focus();
return true;
}
return false;
}
}
// Cancelling the execution
const button = new Button();
// Render the button to create its #element.
button.render();
// The logic controlling the behavior of the button.
button.on( focus , ( evt, [ isForced ] ) => {
// Disallow forcing the focus of this button.
if ( isForced === true ) {
// 参见:[ckeditor5/utils:emittermixin(事件监听机制)](https://www.jianshu.com/p/c6222dbf157d)
evt.stop();
}
}, { priority: high } );
button.focus(); // -> Focusing button, force argument="undefined"
button.focus( true ); // Nothing is logged, the execution has been stopped.
上面有两个逻辑需要注意:
1.priority: high ,用于设置回调函数执行的优先级(顺序),不设置的话,默认为 normal ,低于 high :
const priorities = {
get( priority ) {
if ( typeof priority != number ) {
return this[ priority ] || this.normal;
} else {
return priority;
}
},
highest: 100000,
high: 1000,
normal: 0,
low: -1000,
lowest: -100000
}
2.evt.stop();会终止执行后续的回调函数,见ckeditor5/utils:emittermixin(事件监听机制)第五节fire。
- 更多用法见ui-library#views。
© 版权声明
文章版权归作者所有,未经允许请勿转载。如内容涉嫌侵权,请在本页底部进入<联系我们>进行举报投诉!
THE END



















暂无评论内容