解除行为
解除行为只需调用 yii\base\Component::detachBehavior()
就OK了:
$Component->detachBehavior('myBehavior2');
这样就可以解除已经绑定好的名为 myBehavior2 的行为了。 但是,对于匿名行为,这个方法就无从下手了。不过我们可以一不做二不休,解除所有绑定好的行为:
$Component->detachBehaviors();
这上面两种方法,都会调用到 yii\base\Behavior::detach()
,其代码如下:
public function detach() { // 这得是个名花有主的行为才有解除一说 if ($this->owner) { // 遍历行为定义的事件,一一解除 foreach ($this->events() as $event => $handler) { $this->owner->off($event, is_string($handler) ? [$this, $handler] : $handler); } $this->owner = null; } }
与 yii\base\Behavior::attach()
相反,解除的过程就是干两件事: 一是将 $owner 设置为 null ,表示这个行为没有依附到任何类上。 二是通过Component的 off()
将绑定到类上的事件hanlder解除下来。一句话,善始善终。
行为响应的事件实例
上面的绑定和解除过程,我们看到Yii费了那么大劲,主要就是为了将行为中的事件handler绑定到类中去。 在实际编程时,行为用得最多的,也是对于Compoent各种事件的响应。 通过行为注入,可以在不修改现有类的代码的情况下,更改、扩展类对于事件的响应和支持。 使用这个技巧,可以玩出很炫的花样。 而要将行为与Component的事件关联起来,就要通过 yii\base\Behavior::events()
方法。
上面Behavior基类的代码中,这个方法只是返回了一个空数组,说明不对所依附的Compoent的任何事件产生关联。 但是在实际使用时,往往通过重载这个方法来告诉Yii,这个行为将对Compoent的何种事件,使用哪个方法进行处理。
比如,Yii自带的 yii\behaviors\AttributeBehavior 类,定义了在一个 ActiveRecord 对象的某些事件发生时, 自动对某些字段进行修改的行为。 他有一个很常用的子类 yii\behaviors\TimeStampBehavior 用于将指定的字段设置为一个当前的时间戳。 常用于表示最后修改日期、上次登陆时间等场景。我们以这个行为为例,来分析行为响应事件的原理。
在 yii\behaviors\AttributeBehavior::event()
中,代码如下: