使用 Aspect,可以允许你在指定方法执行的前后插入特定函数。
on 的第一个参数是 eventType, 比如 click, complete 等,需要调用 trigger 主动触发
after / before 的第一个参数是当前实例上的 methodName
on 是纯粹注册一个事件
after / before 在第一次调用时,还担当了将 methodName 包裹起来的作用,在包裹后,调用 method 时,会自动触发 before:methodName
和 after:methodName
事件
可以看出,after / before 的参数以及第一次调用时的行为,都与 on 是不同的。
更直白的理解是,after(type, fn)
应该是在 type 事件触发前,先触发 fn. 含义类似 YUI3 里的 custom event 提供的 after / before
我们该如何取舍?想到几种选择:
保留现有 api,就让 after / before 与 on 存在不一致。
将 after 和 before 改名为 afterMethod / beforeMetohd, 让其含义更直白。
不将 after 和 before 混入 Base,独立出来,成为一个纯粹的 Aspect 模块,调用时使用:
var Aspect = FNX.include('base/aspect');
Aspect.before(object, methodName, callback, context, arg*)
Aspect.after(object, methodName, callback, context, arg*)
第三种方式,是很纯粹的 AOP接口,可以进一步提供更多更强大的功能,还有个很大的好处是,object 参数也可以是一个 Class。
第三种方式的不足之处:普通应用场景下,使用起来有点蛋疼,不如现有的方式。
基于 Base.extend
创建的类,会自动添加上 Aspect
提供的功能。
object.before(methodName, callback, [context])
¶在 object[methodName]
方法执行前,先执行 callback
函数。
var Dialog = Base.extend({
...
show: function() {
console.log(2);
this.element.show();
},
...
});
var dialog = new Dialog();
dialog.before('show', function() {
console.log(1);
});
dialog.after('show', function() {
console.log(3);
});
dialog.show(); // ==> 1, 2, 3
callback
函数在执行时,接收的参数与传给 object[methodName]
参数相同。如果传入了
context
参数,则 callback
里的 this
指向 context
。
var dialog = new Dialog();
dialog.before('show', function(a, b) {
console.log(a);
console.log(b);
});
dialog.show(1, 2); // ==> 1, 2
可以在 callback
中 return false 来阻止原函数执行。
dialog.before('show', function() {
console.log(1);
return false;
});
dialog.after('show', function() {
console.log(3);
});
dialog.show(); // ==> 1
object.after(methodName, callback, [context])
¶在 object[methodName]
方法执行后,再执行 callback
函数。
callback
函数在执行时,接收的参数是 object[methodName]
执行完成后的返回值以及传给 object[methodName]
的参数。如果传入了
context
参数,则 callback
里的 this
指向 context
。
var dialog = new Dialog(); dialog.after('show', function(returned, a, b) { console.log(returned); // show 的返回值 console.log(a); console.log(b); }); dialog.show(1, 2); // ==> undefined, 1, 2
注意
before
和 after
是按注册的先后顺序执行的,先注册先执行。
dialog.before('show', function() {
console.log(1);
});
dialog.before('show', function() {
console.log(2);
});
dialog.show(); // ==> 1, 2