YII中的CComponent,CEvent与Behavior及CActiveRecordBehavior

YII中的CComponent,CEvent与Behavior及CActiveRecordBehavior个人理解

这一块教程少,今天个人理解了下,写了个小例子,有助于理解

完成如下功能,一个JTool类,继承CComponent,当其长度改变时,调用事件,输出"change me".

JTool.php在protected/components 下

<?php

class JTool extends CComponent{

private &#036;_width;


public function getWidth(){


	return &#036;this-&gt;_width ? &#036;this-&gt;_width : 1; 


}





public function setWidth(&#036;width){


	if(&#036;this-&gt;hasEventHandler('onChange')){


		&#036;this-&gt;onChange(new CEvent());


	}


	&#036;this-&gt;_width = &#036;width;


}





public function onChange(&#036;event){


	&#036;this-&gt;raiseEvent('onChange', &#036;event);


}

}

OK,功能已经实现了,找个控制器,执行

$j = new JTool();

$j->onChange = "showChange"; //给事件绑定handle showChange

$j->width = 100; //调用setWidth,解发绑定的事件showChange

function showChange(){

echo 'changed me';

}

现在我们想给JTool添加一个功能,返回长度的100倍,我们可以继承JTool.php写一个方法

class JToolSub extends JTool{

public function get100width(){


	return &#036;this-&gt;width*100;


}

}

OK,功能实现了,这个执行就简单了new JToolSub调用方法即可

上边的这两种办法,就是仅完成功能,下边演示Behavior及events来实现

如何用Behavior来实现上边的增加一个方法,返回长度的100倍的功能呢?

写类JBe

JBe.php在protected/behavior 下

class JBe extends CBehavior{

public function get100width(){


	return &#036;this-&gt;Owner-&gt;width*100;


}

}

OK,功能已经实现了,找个控制器,执行

$j = new JTool();

$j->attachBehavior(‘JBe’, ‘application.behavior.JBe’);

echo $j->get100width();

如何用Behavior实现JTool中的长度改变时,调用一个事件的功能呢?

写类JBe

class JBe extends CBehavior{

public function events(){


	return array_merge(parent::events(),array(


		'onChange'=&gt;'change',


	));


}





public function change(){


	echo 'changed';


}





public function get100width(){


	return &#036;this-&gt;Owner-&gt;width*100;


}

}

OK,功能实现随便找个控制器,执行

$j = new JTool();

$j->attachBehavior(‘JBe’, ‘application.behavior.JBe’);

$j->width = 100;

这里的要点是events方法

返回的数组array(‘onChange’=>‘change’)定义了事件(event)和对应的事件处理方法(event hander)

事件是是Compents(JTool中)定义的,即JTool中的onChange

处理方法同由Behavior(JBe中)类定义的,即JBe中的change

这样子再看CActiveRecordBehavior,其是绑定给CActiveRecord 这个组件的,绑定方法重写behaviors()

CActiveRecordBehavior中的events() 方法返回事件及事处理函数的对应,如:

‘onBeforeSave’=>‘beforeSave’

即组件CActiveRecord中的onBeforeSave这个事件对应的处理函数是

CActiveRecordBehavior中的beforeSave方法

这样子CActiveRecord在调用save()时,触发事件onBeforeSave,调用CActiveRecordBehavior对应的处理函数beforeSave

我们只要写一个CActiveRecordBehavior的子类,重写其中的beforeSave,执行一些操作,然后给CActiveRecord绑定即可

我还有个疑问,在继承CBehavior时,是不是一定要让方法events()反回那个对应关系的数组,如果这里为空,没有默认的对应关系?

好文!

不错!接下来,我正要看db那一块了,正好学习,感谢

的确好文

运行有问题

call_user_func(ShowChange) [<a href=‘function.call-user-func’>function.call-user-func</a>]: First argument is expected to be a valid callback

OK,功能已经实现了,找个控制器,执行

$j = new JTool();

$j->onChange = "showChange"; //给事件绑定handle showChange

$j->width = 100; //调用setWidth,解发绑定的事件showChange

function showChange(){

echo ‘changed me’;

}

$j->onChange = "showChange"; 改成

$j->onChange = array($this, "showChange");