十三、逐行阅读Yii2.0.43源码_Yii框架文件Component.php(3)

 关联阅读 

十一、逐行阅读Yii2.0.43源码_Yii框架文件Component.php(1)

十二、逐行阅读Yii2.0.43源码_Yii框架文件Component.php(2)

十三、逐行阅读Yii2.0.43源码_Yii框架文件Component.php(3)

十四、逐行阅读Yii2.0.43源码_Yii框架文件Component.php(4)

 

目录

一、hasEventHandlers方法,返回$name是否有绑定了对应的事件处理程序,搜索顺序:

 二、on方法,绑定事件

三、off方法,解绑事件

 四、trigger方法,触发事件


一、hasEventHandlers方法,返回$name是否有绑定了对应的事件处理程序,搜索顺序:

1.通配符事件

2.普通事件

3.类级别事件

    /**
     * 返回$name是否有绑定了对应的事件处理程序
     */
    public function hasEventHandlers($name)
    {
        //1. 模式匹配
        $this->ensureBehaviors();
        foreach ($this->_eventWildcards as $wildcard => $handlers) {
            if (!empty($handlers) && StringHelper::matchWildcard($wildcard, $name)) {
                return true;
            }
        }

        return
            //2. 事件数组查找
            !empty($this->_events[$name]) ||
            //3.类级别事件
            Event::hasHandlers($this, $name);
    }

 二、on方法,绑定事件

1. $append为true,将新事件追加事件列表末尾

2. $append为false,将新事件插入事件列表开头

    /**
     * 绑定事件
     * $append为true,将新事件追加事件列表末尾
     * $append为false,将新事件插入事件列表开头
     */
    public function on($name, $handler, $data = null, $append = true)
    {
        $this->ensureBehaviors();

        // 1. 事件名称存在 '*',是一个通配符事件
        if (strpos($name, '*') !== false) {
            if ($append || empty($this->_eventWildcards[$name])) {
                $this->_eventWildcards[$name][] = [$handler, $data];
            } else {
                array_unshift($this->_eventWildcards[$name], [$handler, $data]);
            }
            return;
        }

        //2. 普通事件
        if ($append || empty($this->_events[$name])) {
            $this->_events[$name][] = [$handler, $data];
        } else {
            array_unshift($this->_events[$name], [$handler, $data]);
        }
    }

三、off方法,解绑事件

1. $_events和$_eventWildcards不存在$name,直接返回false

2. $handler为null,删除$name对应的所有事件

3.普通事件,遍历$name事件列表,移除$handler

4.通配符事件

    /**
     * 解绑事件
     */
    public function off($name, $handler = null)
    {
        $this->ensureBehaviors();

        //1. $_events和$_eventWildcards不存在$name,直接返回false
        if (empty($this->_events[$name]) && empty($this->_eventWildcards[$name])) {
            return false;
        }

        //2. $handler为null,删除$name对应的所有事件
        if ($handler === null) {
            unset($this->_events[$name], $this->_eventWildcards[$name]);
            return true;
        }

        $removed = false;
        // 3.普通事件,遍历$name事件列表,移除$handler
        if (isset($this->_events[$name])) {
            foreach ($this->_events[$name] as $i => $event) {
                if ($event[0] === $handler) {
                    unset($this->_events[$name][$i]);
                    $removed = true;
                }
            }
            if ($removed) {
                //重新索引,赋值
                $this->_events[$name] = array_values($this->_events[$name]);
                return true;
            }
        }

        // 4.通配符事件
        if (isset($this->_eventWildcards[$name])) {
            foreach ($this->_eventWildcards[$name] as $i => $event) {
                if ($event[0] === $handler) {
                    unset($this->_eventWildcards[$name][$i]);
                    $removed = true;
                }
            }
            if ($removed) {
                $this->_eventWildcards[$name] = array_values($this->_eventWildcards[$name]);
                // 删除空通配符
                if (empty($this->_eventWildcards[$name])) {
                    unset($this->_eventWildcards[$name]);
                }
            }
        }

        return $removed;
    }

 四、trigger方法,触发事件

1. 合并通配符事件和普通事件处理函数

2.遍历事件处理函数,直到事件被处理,返回

3.类级别事件触发

    /**
     * 触发事件
     */
    public function trigger($name, Event $event = null)
    {
        $this->ensureBehaviors();

        //1. 合并通配符事件和普通事件处理函数
        $eventHandlers = [];
        foreach ($this->_eventWildcards as $wildcard => $handlers) {
            if (StringHelper::matchWildcard($wildcard, $name)) {
                $eventHandlers = array_merge($eventHandlers, $handlers);
            }
        }

        if (!empty($this->_events[$name])) {
            $eventHandlers = array_merge($eventHandlers, $this->_events[$name]);
        }

        //2.遍历事件处理函数,直到事件被处理,返回
        if (!empty($eventHandlers)) {
            if ($event === null) {
                $event = new Event();
            }
            if ($event->sender === null) {
                $event->sender = $this;
            }
            $event->handled = false;
            $event->name = $name;
            foreach ($eventHandlers as $handler) {
                $event->data = $handler[1];
                call_user_func($handler[0], $event);
                // 如果事件已被处理,则停止进一步处理
                if ($event->handled) {
                    return;
                }
            }
        }

        // 3.类级别事件触发
        Event::trigger($this, $name, $event);
    }

总结:

阅读了4个事件相关的方法:

  • hasEventHandlers是否有绑定了对应的事件处理程序
  • on 绑定事件
  • off 解绑事件
  • trigger 触发事件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值