>

Event

事件系统是Exact的基础,Watcher对象提供的实例方法,实现了监听、移除和派发任意类型事件的功能。Store、Element和Component等都混入了这些事件方法。

On / Off / Once

用`on`方法来监听指定类型的事件,用`off`方法来移除相应类型的事件处理函数。用例如下:

var onChange = function() {};
watcher.on('click', function() {});
watcher.on({
  click: function() {},
  change: onChange,
  invalid: function() {},
} );
watcher.off('change', onChange);  // 移除了change事件处理函数onChange
watcher.off('click');             // 移除了所有click事件处理函数
watcher.off();                    // 移除了所有类型事件处理函数

特别地,用`once`监听事件,处理函数在第一次触发之后被自动移除。

watcher.once('initialized', function(event) {
  console.log(event.type);
});
watcher.send('initialized');    // 输出:"initialized"
watcher.send('initialized');    // 没有新的输出

对于DOM事件,默认监听的是冒泡阶段的事件。如果要监听捕获阶段的事件,请在事件类型前加一个`!`,像这样:

watcher.on('!click', function() {});

Send / Emit

用`send`或`emit`方法来派发事件,以及传递附带参数。 对于`send`方法派发的事件,处理函数接受到的第一个参数为Event对象,而`emit`会忽略事件本身,只向处理函数传递附带参数。 用例如下:

function onClick(event, value) {
  console.log(event.type, value);
}
function onMessage(value) {
  console.log(value);
}
watcher.on('click' onClick);
watcher.send('click');                      // 输出:"click", undefined
watcher.send('click', 'ok');                // 输出:"click", "ok"
watcher.emit('click', {type: 'not click'}); // 输出:"not click", undefined
watcher.on('message', onMessage);
watcher.emit('message', 'ok');              // 输出:"ok"

在Exact内部,默认使用send方法派发自定义事件和转发DOM事件,相应处理函数接受到的第一个参数始终是Event对象。

Event Type & Event Name

通常在监听键盘事件时,我们会关心用户按下的键名。同样,当某个属性的值发生改变或验证失败时,我们会关心这个属性的名字。 为此,Exact的事件系统特别照顾到了这种情况,允许同一类型的事件有不同的事件名,这使得事件的监听和移除方法更为灵活。

function onEnter(event) {
  console.log('key `' + event.name + '` is pressed');
}
function onChanged(event) {
  console.log('prop `' + event.name + '` is changed');
}
function onLabelChanged(event) {
  console.log('prop `label` is changed, really');
}
component.on('keypress.enter', onEnter);// 按下Enter键时,才会输出:key `enter` is pressed
component.on('changed', onChanged);
component.on('changed.label', onLabelChanged);
component.send('changed.label');        // 输出:prop `label` is changed
                                        // 输出:prop `label` is changed, really
component.send('changed.other');        // 输出:prop `other` is changed
component.off('keypress.enter');        // 只移除了name为`enter`的keypress事件的处理函数
component.off('changed');               // 移除了所有changed事件的处理函数,无论name是什么