标签:
接上次的组件(component)代码:
1 /** 2 * Returns a list of behaviors that this component should behave as. 3 * 定义该对象中要用到的 behavior,返回一个行为列表 4 * Child classes may override this method to specify the behaviors they want to behave as. 5 * 6 * 行为配置数组格式如下: 7 * 8 * ```php 9 * ‘behaviorName‘ => [ 10 * ‘class‘ => ‘BehaviorClass‘, 11 * ‘property1‘ => ‘value1‘, 12 * ‘property2‘ => ‘value2‘, 13 * ] 14 * ``` 15 * Behaviors declared in this method will be attached to the component automatically (on demand). 16 * 定义该对象中要用到的 behavior 17 * @return array 行为配置. 18 */ 19 public function behaviors() 20 { 21 return []; 22 } 23 24 /** 25 * Returns a value indicating whether there is any handler attached to the named event. 26 * 判断 _events 中的一个 event 是否具有事件处理程序 27 * @param string $name 事件名 28 * @return boolean whether there is any handler attached to the event. 29 */ 30 public function hasEventHandlers($name) 31 { 32 $this->ensureBehaviors(); 33 //短路写法,判断调用_events中是否有$name事件,没有直接返回false,否则,调用Event类中的的方法判断是否有处理程序 34 return !empty($this->_events[$name]) || Event::hasHandlers($this, $name); 35 } 36 37 /** 38 * Attaches an event handler to an event. 39 * 添加事件处理程序到事件 40 * The event handler must be a valid PHP callback. The following are 41 * some examples: 42 * 事件处理程序必须是有效的PHP回调函数,方便内置方法call_user_fucn()调用 ,例如: 43 * ``` 44 * function ($event) { ... } // 匿名函数 45 * [$object, ‘handleClick‘] // 以数组形式表示的对象的方法 46 * [‘Page‘, ‘handleClick‘] // 静态方法 47 * ‘handleClick‘ // 全局函数,只写函数名 48 * ``` 49 * 50 * The event handler must be defined with the following signature, 51 * 时间处理程序的定义格式: 52 * ``` 53 * function ($event) 54 * ``` 55 * 56 * where `$event` is an [[Event]] object which includes parameters associated with the event. 57 * `$event`是一个包含于event相关联的[[Event]]对象 58 * @param string $name 事件名 59 * @param callable $handler 事件处理函数 60 * @param mixed $data the data to be passed to the event handler when the event is triggered. 61 * When the event handler is invoked, this data can be accessed via [[Event::data]]. 62 * @param boolean $append whether to append new event handler to the end of the existing 63 * handler list. If false, the new handler will be inserted at the beginning of the existing 64 * handler list. 65 * @see off() 66 */ 67 public function on($name, $handler, $data = null, $append = true) 68 { 69 $this->ensureBehaviors();//确保所有的行为都加载到组件中 70 if ($append || empty($this->_events[$name])) {//$append 判断是否添加到事件(event)的后面,且确保_events中有该事件 71 $this->_events[$name][] = [$handler, $data];//将事件处理程序和参数添加到event数组中 72 } else {//否则,添加到event数组的前面 73 array_unshift($this->_events[$name], [$handler, $data]); 74 } 75 } 76 77 /** 78 * Detaches an existing event handler from this component. 79 * This method is the opposite of [[on()]]. 80 * 81 * [[on()]]方法的反方法,用于删除事件处理程序 82 * 83 * @param string $name 事件名 84 * @param callable $handler 事件处理程序 85 * 如果$handler 为空,清除该事件的所有时间处理程序 86 * @return boolean if a handler is found and detached 87 * @see on() 88 */ 89 public function off($name, $handler = null) 90 { 91 $this->ensureBehaviors();//确保所有的行为都加载到组件中 92 if (empty($this->_events[$name])) {//如果_events中没有该事件,也就是事件不存在 93 return false; //返回false 94 } 95 if ($handler === null) {//如果事件处理程序为空 96 unset($this->_events[$name]);//清除该事件的所有事件处理程序 97 return true; //返回true 98 } else { 99 $removed = false; //删除标记 100 //否则遍历该事件 根据on()方法的格式可以知道,$event[0]是事件处理程序,$event[1]是数据 101 foreach ($this->_events[$name] as $i => $event) { 102 if ($event[0] === $handler) {//判断事件处理程序是否符合 103 unset($this->_events[$name][$i]);//删除该事件处理程序 104 $removed = true; 105 } 106 } 107 if ($removed) {//判断是否删除成功 108 //如果删除成功,调用array_values方法重新赋值,格式化索引 109 $this->_events[$name] = array_values($this->_events[$name]); 110 } 111 return $removed;//返回删除成功标记 112 } 113 } 114 115 /** 116 * Triggers an event. 117 * This method represents the happening of an event. It invokes 118 * all attached handlers for the event including class-level handlers. 119 * 120 * 触发器方法 121 * 122 * @param string $name 事件名 123 * @param Event $event 事件参数. 如果未设置,一个默认的 [[Event]] 对象将被创建. 124 */ 125 public function trigger($name, Event $event = null) 126 { 127 $this->ensureBehaviors(); 128 if (!empty($this->_events[$name])) { 129 if ($event === null) { 130 // 构建Event对象,为传入到handler函数中做准备 131 $event = new Event; 132 } 133 if ($event->sender === null) { 134 $event->sender = $this; 135 } 136 $event->handled = false; 137 $event->name = $name; 138 foreach ($this->_events[$name] as $handler) { 139 //遍历_events取得处理程序名和数据 140 $event->data = $handler[1];//给[[Event]] 的data属性赋值 141 call_user_func($handler[0], $event);//通过内置函数call_user_func()调用事件处理函数,$event作为参数 142 // stop further handling if the event is handled 143 // 事件是否被handle,当handled被设置为true时,执行到这个event的时候,会停止,并忽略剩下的event--不太明白,以后追加吧 144 if ($event->handled) { 145 return; 146 } 147 } 148 } 149 // invoke class-level attached handlers 150 //[[Event]] 的静态方法,触发类级别的事件处理程序 151 Event::trigger($this, $name, $event); 152 } 153 154 /** 155 * Returns the named behavior object. 156 * 获取行为类 157 * @param string $name the behavior name 158 * @return null|Behavior the behavior object, or null if the behavior does not exist 159 */ 160 public function getBehavior($name) 161 { 162 $this->ensureBehaviors(); 163 return isset($this->_behaviors[$name]) ? $this->_behaviors[$name] : null;//_behaviors中的行为类存在,返回行为类名,否则返回空 164 } 165 166 /** 167 * Returns all behaviors attached to this component. 168 * 169 * 获取所有的行为类 170 * @return Behavior[] list of behaviors attached to this component 171 */ 172 public function getBehaviors() 173 { 174 $this->ensureBehaviors(); 175 return $this->_behaviors;//直接返回了_behaviors 176 } 177 178 /** 179 * Attaches a behavior to this component. 180 * 添加一个行为到组件 181 * 通过提供的配置文件创建一个Behavior对象,通过调用 [[Behavior::attach()]] 方法添加行为到组件. 182 * @param string $name the name of the behavior. 183 * @param string|array|Behavior $behavior 行为配置,可选项如下: 184 * 185 * - 一个行为类 186 * - 一个字符串形式的指定行为类 187 * - 一个配置文件数组,通过调用[[Yii::createObject()]] 创建一个行为对象. 188 * 189 * @return Behavior the behavior object 190 * @see detachBehavior() 191 */ 192 public function attachBehavior($name, $behavior) 193 { 194 $this->ensureBehaviors(); 195 return $this->attachBehaviorInternal($name, $behavior); 196 } 197 198 /** 199 * Attaches a list of behaviors to the component. 200 * 添加行为到组件 201 * 行为类通过行为名索引,且必须是一个 [[Behavior]] 对象指定的行为类或者一个配置数组 202 * 203 * @param array $behaviors list of behaviors to be attached to the component 204 * @see attachBehavior() 205 */ 206 public function attachBehaviors($behaviors) 207 { 208 $this->ensureBehaviors(); 209 foreach ($behaviors as $name => $behavior) { 210 $this->attachBehaviorInternal($name, $behavior); 211 } 212 } 213 214 /** 215 * Detaches a behavior from the component. 216 * 从组件解除行为 217 * The behavior‘s [[Behavior::detach()]] method will be invoked. 218 * 实现方式是调用Behavior类中的detach()方法 219 * @param string $name the behavior‘s name. 220 * @return null|Behavior the detached behavior. Null if the behavior does not exist. 221 */ 222 public function detachBehavior($name) 223 { 224 $this->ensureBehaviors(); 225 if (isset($this->_behaviors[$name])) { 226 $behavior = $this->_behaviors[$name]; 227 unset($this->_behaviors[$name]); 228 $behavior->detach(); 229 return $behavior; 230 } else { 231 return null; 232 } 233 } 234 235 /** 236 * Detaches all behaviors from the component. 237 * 解除所有的行为 238 */ 239 public function detachBehaviors() 240 { 241 $this->ensureBehaviors(); 242 foreach ($this->_behaviors as $name => $behavior) { 243 $this->detachBehavior($name); 244 } 245 } 246 247 /** 248 * Makes sure that the behaviors declared in [[behaviors()]] are attached to this component. 249 * 确保定义的行为都被添加到组件 250 */ 251 public function ensureBehaviors() 252 { 253 if ($this->_behaviors === null) {// 如果$this->_behaviors为空 254 $this->_behaviors = []; 255 foreach ($this->behaviors() as $name => $behavior) {//遍历$this->behaviors()中的behaviors,并存储到$this->_behaviors数组中 256 $this->attachBehaviorInternal($name, $behavior); 257 } 258 } 259 } 260 261 /** 262 * Attaches a behavior to this component. 263 * 私有方法 添加一个行为到组件 264 * @param string|integer $name 行为名. 如果是整数,说明该行为是匿名的 265 * @param string|array|Behavior $behavior the behavior to be attached 266 * @return Behavior the attached behavior. 267 */ 268 private function attachBehaviorInternal($name, $behavior) 269 { 270 if (!($behavior instanceof Behavior)) { 271 // $behavior不是Behavior对象,就认为是配置,通过它创建一个 272 $behavior = Yii::createObject($behavior); 273 } 274 if (is_int($name)) {//行为名师整数 275 $behavior->attach($this);//绑定行为到组件 276 $this->_behaviors[] = $behavior; 277 } else { 278 if (isset($this->_behaviors[$name])) { 279 // 如果有同名的行为存在就先解绑掉 280 $this->_behaviors[$name]->detach(); 281 } 282 $behavior->attach($this);//重新绑定行为到组件 283 $this->_behaviors[$name] = $behavior; 284 } 285 return $behavior; 286 }
标签:
原文地址:http://www.cnblogs.com/isleep/p/5397525.html