Yii源码阅读笔记(七)
接上次的组件(component)代码:
/** * Returns a list of behaviors that this component should behave as. * 定义该对象中要用到的 behavior,返回一个行为列表 * Child classes may override this method to specify the behaviors they want to behave as. * * 行为配置数组格式如下: * * ```php * 'behaviorName' => [ * 'class' => 'BehaviorClass', * 'property1' => 'value1', * 'property2' => 'value2', * ] * ``` * Behaviors declared in this method will be attached to the component automatically (on demand). * 定义该对象中要用到的 behavior * @return array 行为配置. */ public function behaviors() { return []; } /** * Returns a value indicating whether there is any handler attached to the named event. * 判断 _events 中的一个 event 是否具有事件处理程序 * @param string $name 事件名 * @return boolean whether there is any handler attached to the event. */ public function hasEventHandlers($name) { $this->ensureBehaviors(); //短路写法,判断调用_events中是否有$name事件,没有直接返回false,否则,调用Event类中的的方法判断是否有处理程序 return !empty($this->_events[$name]) || Event::hasHandlers($this, $name); } /** * Attaches an event handler to an event. * 添加事件处理程序到事件 * The event handler must be a valid PHP callback. The following are * some examples: * 事件处理程序必须是有效的PHP回调函数,方便内置方法call_user_fucn()调用 ,例如: * ``` * function ($event) { ... } // 匿名函数 * [$object, 'handleClick'] // 以数组形式表示的对象的方法 * ['Page', 'handleClick'] // 静态方法 * 'handleClick' // 全局函数,只写函数名 * ``` * * The event handler must be defined with the following signature, * 时间处理程序的定义格式: * ``` * function ($event) * ``` * * where `$event` is an [[Event]] object which includes parameters associated with the event. * `$event`是一个包含于event相关联的[[Event]]对象 * @param string $name 事件名 * @param callable $handler 事件处理函数 * @param mixed $data the data to be passed to the event handler when the event is triggered. * When the event handler is invoked, this data can be accessed via [[Event::data]]. * @param boolean $append whether to append new event handler to the end of the existing * handler list. If false, the new handler will be inserted at the beginning of the existing * handler list. * @see off() */ public function on($name, $handler, $data = null, $append = true) { $this->ensureBehaviors();//确保所有的行为都加载到组件中 if ($append || empty($this->_events[$name])) {//$append 判断是否添加到事件(event)的后面,且确保_events中有该事件 $this->_events[$name][] = [$handler, $data];//将事件处理程序和参数添加到event数组中 } else {//否则,添加到event数组的前面 array_unshift($this->_events[$name], [$handler, $data]); } } /** * Detaches an existing event handler from this component. * This method is the opposite of [[on()]]. * * [[on()]]方法的反方法,用于删除事件处理程序 * * @param string $name 事件名 * @param callable $handler 事件处理程序 * 如果$handler 为空,清除该事件的所有时间处理程序 * @return boolean if a handler is found and detached * @see on() */ public function off($name, $handler = null) { $this->ensureBehaviors();//确保所有的行为都加载到组件中 if (empty($this->_events[$name])) {//如果_events中没有该事件,也就是事件不存在 return false; //返回false } if ($handler === null) {//如果事件处理程序为空 unset($this->_events[$name]);//清除该事件的所有事件处理程序 return true; //返回true } else { $removed = false; //删除标记 //否则遍历该事件 根据on()方法的格式可以知道,$event[0]是事件处理程序,$event[1]是数据 foreach ($this->_events[$name] as $i => $event) { if ($event[0] === $handler) {//判断事件处理程序是否符合 unset($this->_events[$name][$i]);//删除该事件处理程序 $removed = true; } } if ($removed) {//判断是否删除成功 //如果删除成功,调用array_values方法重新赋值,格式化索引 $this->_events[$name] = array_values($this->_events[$name]); } return $removed;//返回删除成功标记 } } /** * Triggers an event. * This method represents the happening of an event. It invokes * all attached handlers for the event including class-level handlers. * * 触发器方法 * * @param string $name 事件名 * @param Event $event 事件参数. 如果未设置,一个默认的 [[Event]] 对象将被创建. */ public function trigger($name, Event $event = null) { $this->ensureBehaviors(); if (!empty($this->_events[$name])) { if ($event === null) { // 构建Event对象,为传入到handler函数中做准备 $event = new Event; } if ($event->sender === null) { $event->sender = $this; } $event->handled = false; $event->name = $name; foreach ($this->_events[$name] as $handler) { //遍历_events取得处理程序名和数据 $event->data = $handler[1];//给[[Event]] 的data属性赋值 call_user_func($handler[0], $event);//通过内置函数call_user_func()调用事件处理函数,$event作为参数 // stop further handling if the event is handled // 事件是否被handle,当handled被设置为true时,执行到这个event的时候,会停止,并忽略剩下的event--不太明白,以后追加吧 if ($event->handled) { return; } } } // invoke class-level attached handlers //[[Event]] 的静态方法,触发类级别的事件处理程序 Event::trigger($this, $name, $event); } /** * Returns the named behavior object. * 获取行为类 * @param string $name the behavior name * @return null|Behavior the behavior object, or null if the behavior does not exist */ public function getBehavior($name) { $this->ensureBehaviors(); return isset($this->_behaviors[$name]) ? $this->_behaviors[$name] : null;//_behaviors中的行为类存在,返回行为类名,否则返回空 } /** * Returns all behaviors attached to this component. * * 获取所有的行为类 * @return Behavior[] list of behaviors attached to this component */ public function getBehaviors() { $this->ensureBehaviors(); return $this->_behaviors;//直接返回了_behaviors } /** * Attaches a behavior to this component. * 添加一个行为到组件 * 通过提供的配置文件创建一个Behavior对象,通过调用 [[Behavior::attach()]] 方法添加行为到组件. * @param string $name the name of the behavior. * @param string|array|Behavior $behavior 行为配置,可选项如下: * * - 一个行为类 * - 一个字符串形式的指定行为类 * - 一个配置文件数组,通过调用[[Yii::createObject()]] 创建一个行为对象. * * @return Behavior the behavior object * @see detachBehavior() */ public function attachBehavior($name, $behavior) { $this->ensureBehaviors(); return $this->attachBehaviorInternal($name, $behavior); } /** * Attaches a list of behaviors to the component. * 添加行为到组件 * 行为类通过行为名索引,且必须是一个 [[Behavior]] 对象指定的行为类或者一个配置数组 * * @param array $behaviors list of behaviors to be attached to the component * @see attachBehavior() */ public function attachBehaviors($behaviors) { $this->ensureBehaviors(); foreach ($behaviors as $name => $behavior) { $this->attachBehaviorInternal($name, $behavior); } } /** * Detaches a behavior from the component. * 从组件解除行为 * The behavior's [[Behavior::detach()]] method will be invoked. * 实现方式是调用Behavior类中的detach()方法 * @param string $name the behavior's name. * @return null|Behavior the detached behavior. Null if the behavior does not exist. */ public function detachBehavior($name) { $this->ensureBehaviors(); if (isset($this->_behaviors[$name])) { $behavior = $this->_behaviors[$name]; unset($this->_behaviors[$name]); $behavior->detach(); return $behavior; } else { return null; } } /** * Detaches all behaviors from the component. * 解除所有的行为 */ public function detachBehaviors() { $this->ensureBehaviors(); foreach ($this->_behaviors as $name => $behavior) { $this->detachBehavior($name); } } /** * Makes sure that the behaviors declared in [[behaviors()]] are attached to this component. * 确保定义的行为都被添加到组件 */ public function ensureBehaviors() { if ($this->_behaviors === null) {// 如果$this->_behaviors为空 $this->_behaviors = []; foreach ($this->behaviors() as $name => $behavior) {//遍历$this->behaviors()中的behaviors,并存储到$this->_behaviors数组中 $this->attachBehaviorInternal($name, $behavior); } } } /** * Attaches a behavior to this component. * 私有方法 添加一个行为到组件 * @param string|integer $name 行为名. 如果是整数,说明该行为是匿名的 * @param string|array|Behavior $behavior the behavior to be attached * @return Behavior the attached behavior. */ private function attachBehaviorInternal($name, $behavior) { if (!($behavior instanceof Behavior)) { // $behavior不是Behavior对象,就认为是配置,通过它创建一个 $behavior = Yii::createObject($behavior); } if (is_int($name)) {//行为名师整数 $behavior->attach($this);//绑定行为到组件 $this->_behaviors[] = $behavior; } else { if (isset($this->_behaviors[$name])) { // 如果有同名的行为存在就先解绑掉 $this->_behaviors[$name]->detach(); } $behavior->attach($this);//重新绑定行为到组件 $this->_behaviors[$name] = $behavior; } return $behavior; }
Yii源码阅读笔记(七)的更多相关文章
- Yii源码阅读笔记(一)
今天开始阅读yii2的源码,想深入了解一下yii框架的工作原理,同时学习一下优秀的编码规范和风格.在此记录一下阅读中的小心得. 每个框架都有一个入口文件,首先从入口文件开始,yii2的入口文件位于we ...
- Yii源码阅读笔记(八)
前面阅读了Yii2的两个基本类Object和Component,了解了Yii的三个重要概念属性.事件.行为,下面开始阅读Event类,Event类是所有事件类的基类: <?php /** * @ ...
- Yii源码阅读笔记(三)
接着上次的继续阅读BaseYii.php vendor/yiisoft/yii2/BaseYii.php—— public static function getRootAlias($alias)// ...
- Yii源码阅读笔记(二)
接下来阅读BaseYii.php vendor/yiisoft/yii2/BaseYii.php—— namespace yii; use yii\base\InvalidConfigExceptio ...
- Yii源码阅读笔记(三十五)
Container,用于动态地创建.注入依赖单元,映射依赖关系等功能,减少了许多代码量,降低代码耦合程度,提高项目的可维护性. namespace yii\di; use ReflectionClas ...
- Yii源码阅读笔记(三十四)
Instance类, 表示依赖注入容器或服务定位器中对某一个对象的引用 namespace yii\di; use Yii; use yii\base\InvalidConfigException; ...
- Yii源码阅读笔记(三十三)
ServiceLocator,服务定位类,用于yii2中的依赖注入,通过以ID为索引的方式缓存服务或则组件的实例来定位服务或者组件: namespace yii\di; use Yii; use Cl ...
- Yii源码阅读笔记(三十二)
web/Application类的注释,继承base/Application类,针对web应用的一些处理: namespace yii\web; use Yii; use yii\base\Inval ...
- Yii源码阅读笔记(三十一)
Widget类中开始,获取视图对象,获取widget ID,渲染视图,获取路径方法注释: private $_id; /** * Returns the ID of the widget. * 返回插 ...
随机推荐
- jquery require.js AMD
一.为什么要用require.js? 最早的时候,所有Javascript代码都写在一个文件里面,只要加载这一个文件就够了.后来,代码越来越多,一个文件不够了,必须分成多个文件,依次加载.下面的网页代 ...
- VBScript [ 译 ]
VBScript ( Visual Basic Scripting Edition) 使用COM 来和宿主环境交互.从Microsoft Windows 98 开始的所有的微软桌面操作系统的relea ...
- 思考探索,如何才能高效访问我的这个DataTable?
需求 一切都是空的,除了Money,只有需求才是最真的,你懂的. 最近接到个略显棘手的需求,思索再三,想出两种方法,可觉得都不太好,这里与大家讨论一下. 需求如下: 用户需要在现有的某个grid中添加 ...
- LightOJ 1248 Dice (III) 概率
Description Given a dice with n sides, you have to find the expected number of times you have to thr ...
- HDU 4974 Dracula and Ethan 优先队列
Dracula and Ethan Time Limit: 1 Sec Memory Limit: 256 MB Description Dragon is watching competition ...
- 【转】cloudera新增用户权限配置
转自 http://lookqlp.iteye.com/blog/2189119 . 配置起来较复杂,需要在有测试环境之后再进行配置测试. 之后是有上HUE的计划的,所以这个也是一定要做的. ...
- Hark的数据结构与算法练习之珠排序
---恢复内容开始--- 算法说明 珠排序是分布排序的一种. 说实在的,这个排序看起来特别的巧妙,同时也特别好理解,不过不太容易写成代码,哈哈. 这里其实分析的特别好了,我就不画蛇添足啦. 大家看一 ...
- Oracle创建表空间和表
创建表空间和表ORACLE物理上是由磁盘上的以下几种文件:数据文件和控制文件和LOGFILE构成的oracle中的表就是一张存储数据的表.表空间是逻辑上的划分.方便管理的.数据表空间 (Tablesp ...
- Revit二次开发示例:ErrorHandling
本示例介绍了Revit的错误处理. #region Namespaces using System; using System.Collections.Generic; using Autodes ...
- 终于把HDU的第一页做完了
Today is worth to be commemorate for that I have eventually worked out all the questions in the firs ...