YII2.0框架行为(Behavior)深入详解(6)

没有任何预先注入的行为,所以,这个调用没有用。 但是对于子类,你可能重载了 yii\base\Compoent::behaviros() 来预先注入一些行为。 那么,这个函数会将这些行为先注入进来。

从上面的代码中,自然就看到了接下来要说的第三个东东, yii\base\Component\attachBehaviorInternal():

private function attachBehaviorInternal($name, $behavior)
{
 // 不是 Behavior 实例,说是只是类名、配置数组,那么就创建出来吧
 if (!($behavior instanceof 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;
}

首先要注意到,这是一个private成员。其实在Yii中,所有后缀为 *Internal 的方法,都是私有的。 这个方法干了这么几件事:

  • 如果 $behavior 参数并非是一个 Behavior 实例,就以之为参数,用 Yii::createObject() 创建出来。
  • 如果以匿名行为的形式绑定行为,那么直接将行为附加在这个类上。
  • 如果是命名行为,先看看是否有同名的行为已经绑定在这个类上,如果有,用后来的行为取代之前的行为。

yii\base\Component::attachBehaviorInternal() 中, 以 $this 为参数调用了 yii\base\Behavior::attach() 。 从而,引出了跟绑定相关的最后一个家伙 yii\base\Behavior::attach() , 这也是前面我们讲行为的要素时没讲完的。先看看代码:

public function attach($owner)
{
 $this->owner = $owner;
 foreach ($this->events() as $event => $handler) {
  $owner->on($event, is_string($handler) ? [$this, $handler] :
   $handler);
 }
}

上面的代码干了两件事:

  • 设置好行为的 $owner ,使得行为可以访问、操作所依附的对象
  • 遍历行为中的 events() 返回的数组,将准备响应的事件,通过所依附类的 on() 绑定到类上

说了这么多,关于绑定,做个小结:

  • 绑定的动作从Component发起;
  • 静态绑定通过重载 yii\base\Componet::behaviors() 实现;
  • 动态绑定通过调用 yii\base\Component::attachBehaviors() 实现;
  • 行为还可以通过为 Component 配置 as 配置项进行绑定;
  • 行为有匿名行为和命名行为之分,区别在于绑定时是否给出命名。 命名行为可以通过其命名进行标识,从而有针对性地进行解除等操作;

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/5482.html