首页>文档>Rouse开发文档>JS Hooks介绍与使用

需要支持?

如果通过文档没办法解决您的问题,请提交工单获取我们的支持!

JS Hooks介绍与使用

致敬WordPress Hooks,开发了 Javascript 版的钩子。不依托于任何第三方库,可独立运行。

什么是钩子

钩子分为 Action 和 Filter 两种。

  • Action:动作,执行到代码这个位置时,同时调用其他方法。
  • Filter:过滤器,代码在这个位置可能需要过滤数据,数据通过参数传递给外部方法后返回。

无论WordPress还是Javascript,其目的都是:在代码正常执行过程中为二次开发预留的接口。从而实现:一定程度上无需修改源代码而实现二次开发。可以理解为:

  1. 编写一套通用的工作流。工作流本身的编写人提前考虑到一些可能的情况。并在考虑到的情况中预埋钩子。
  2. 接下来,执行人在执行工作流前,预先添加工作流中可能用得到的钩子,然后再执行工作流。当工作流执行到预埋钩子的位置时,被添加的方法得到调用。

Action钩子示例

有下面的工作流:

开始-步骤1-步骤2-步骤3-步骤4-结束

在这个流程中,我们提前考虑到:当步骤2执行完成后,可能有其他的功能需要同时执行
但是我们不知道何时执行完步骤2。因此使用Action钩子

于是,工作流(源代码)的编写人(开发人员)在编写源代码时,在步骤2结束的代码后,预埋了“do_action”钩子,并告知了执行人(用户)动作名称。

最终源代码发布给执行人(用户)使用时,就可以通过“add_action”在步骤2执行完成后同时执行工作流以外的联动方法

Filter过滤器示例

有下面的工作流:

开始-步骤1-步骤2-步骤3-步骤4-结束

在这个流程中,我们提前考虑到:步骤3的 数据可能会被再次处理 后流转到下一个步骤。
但是我们不知道步骤3的原始数据,也不知道何时执行完步骤3。因此使用Filter钩子

于是,工作流(源代码)的编写人(开发人员)在编写源代码时,在步骤3处理完后的数据中,预埋了“apply_filters”钩子,并告知了执行人(用户)过滤器名称。

最终源代码发布给执行人(用户)使用时,就可以通过“add_filter”对步骤3的数据进行外部处理后返回,步骤4就能得到外部处理的结果。

类比WordPress钩子

WordPress钩子同样是这个原理。例如:wp的the_content过滤器。在输出文章数据的时候,如果发现用户添加过the_content过滤器,就使用用户过滤返回后的数据,于是输出的文章内容就是用户使用钩子修改的内容了。
当然,用户在添加这个钩子的时候,并不知道文章内容是什么,所以也不知道如何修改。因此过滤器接收参数。用户在过滤的时候就可以根据原始内容就行过滤。然后再返回。

方法名及参数

do_action

do_action(钩子名称:String, 参数1, 参数2…)
预埋钩子,执行“add_action”的动作钩子,并提供动作的额外参数。

add_action

add_action(钩子名称:String, 回调函数:Function, 优先级:Number)
添加钩子动作,当代码运行到“do_action”时,联动同名的操作。联动的回调参数接收“do_action”传递的参数。

  • 默认优先级:10
  • 逻辑上完全相同(===)的同一个钩子,只会添加一次

例:在下面的工作流中,根据当前时间判断是早上还是晚上。并调用不同的外部方法

//==========添加可用钩子============
add_action('in_the_night',function(time){
    console.log("It's " + time + ", I have to sleep.");
});
add_action('in_the_morning',function(time){
    console.log("It's " + time + ", I have to go to school.");
});
//==========正常的代码工作流============
var date = new Date(),
    hour = date.getHours(),
    minute = date.getHours(),
    time = hour + ":" + minute;
if (hour >= 21 && hour <= 23) {
    console.log('Good night!');
    do_action('in_the_night', time);
}
if (hour >= 6 && hour <= 9) {
    console.log('Good morning!');
    do_action('in_the_morning', time);
}
//==========运行结果===========
// 在6点~9点间,屏幕输出:
// Good morning!
// It's (当前时间), I have to go to school.
//
// 在21点~23点间,屏幕输出:
// Good night!
// It's (当前时间), I have to sleep.

apply_filters

过滤结果 = apply_filters(钩子名称:String, 被过滤的参数, 额外参数1, 额外参数2…)
预埋过滤器,执行“add_filter”的过滤器,并提供被过滤的数据。
若添加的过滤器有多个,则被过滤的数据为上一个过滤器返回的数据。

add_filter

add_filter(钩子名称:String, 回调函数:Function, 优先级:Number)

添加钩子过滤器,当代码运行到“apply_filters”时,运行回调函数,在函数中并返回过滤后的参数。

  • 必须返回参数,原则上返回的过滤后的参数应该与被过滤的参数类型、结构相同
  • 默认优先级:10
  • 逻辑上完全相同(===)的同一个钩子,只会添加一次

例:有一个students的数组中包含每个学生的姓名、年龄、和自我介绍。读取自我介绍时进行过滤:当学生没有自我介绍时,自动根据名字和年龄生成自我介绍。

//==========添加可用钩子============
add_action('introduce_oneself',function(introduce_original, name, age){
    if (introduce_original == "") {
        //没有自我介绍,自动根据额外的参数(姓名和年龄)自动生成
        return "My name is " + name + ", I am " + age + " years old.";
    } else {
        //有自我介绍,不作处理,直接返回
        return introduce_original;
    }
});
//==========正常的代码工作流============
var students = [
    {
        name: "Mary",
        age: 12,
        introduce: ""
    },
    {
        name: "Bob",
        age: 13,
        introduce: "I'm Bob, I like football."
    }
];
//输出自我介绍
for (var i = 0; i < students.length; i++) {
    // 执行过滤器,给过滤器传入被过滤的参数(introduce)、额外参数(name,age)
    var introduce_filtered = apply_filters("introduce_oneself", students[i].introduce, students[i].name, students[i].age);
    console.log(introduce_filtered);
}
//==========运行结果===========
// 屏幕输出:
// My name is Mary, I am 12 years old.
// I'm Bob, I like football.

remove_action / remove_filter

remove_action(钩子名称:String, 回调函数:Function)
remove_filter(钩子名称:String, 回调函数:Function)

只有Function完全相同(===)时,才会被移除。与WordPress的PHP钩子不同的是,无需提供优先级即可移除。

例:

//==========添加可用钩子============
// Take some apple.
function take_apple(original_apple) {
    return original_apple - 3;
}
add_filter('count_apple',take_apple);
// Put them back
remove_filter('count_apple',take_apple);
//==========正常的代码工作流============
var original_apple = 5;
var new_apple = apply_filters("count_apple", original_apple);
console.log("There are " + new_apple + " apples.");
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索