YII中的CComponent,CEvent与Behavior及CActiveRecordBehavior

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

JTool.php在protected/components 下

  1. <?php
  2. classJToolextendsCComponent{
  3. private$_width;
  4. publicfunctiongetWidth(){
  5. return$this->_width?$this->_width:1;
  6. }
  7. publicfunctionsetWidth($width){
  8. if($this->hasEventHandler('onChange')){
  9. $this->onChange(newCEvent());
  10. }
  11. $this->_width=$width;
  12. }
  13. publicfunctiononChange($event){
  14. $this->raiseEvent('onChange',$event);
  15. }
  16. }

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

  1. $j=newJTool();
  2. $j->onChange=array($this,"showChange");//给事件绑定handleshowChange
  3. $j->width=100;//调用setWidth,解发绑定的事件showChange
  4. functionshowChange(){
  5. echo'changedme';
  6. }


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

  1. classJToolSubextendsJTool{
  2. publicfunctionget100width(){
  3. return$this->width*100;
  4. }
  5. }

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





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

如何用Behavior来实现上边的增加一个方法,返回长度的100倍的功能呢?
写类JBe
JBe.php在protected/behavior 下

  1. classJBeextendsCBehavior{
  2. publicfunctionget100width(){
  3. return$this->Owner->width*100;
  4. }
  5. }

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

  1. $j=newJTool();
  2. $j->attachBehavior('JBe','application.behavior.JBe');
  3. echo$j->get100width();


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

  1. classJBeextendsCBehavior{
  2. publicfunctionevents(){
  3. returnarray_merge(parent::events(),array(
  4. 'onChange'=>'change',
  5. ));
  6. }
  7. publicfunctionchange(){
  8. echo'changed';
  9. }
  10. publicfunctionget100width(){
  11. return$this->Owner->width*100;
  12. }
  13. }

OK,功能实现随便找个控制器,执行
  1. $j=newJTool();
  2. $j->attachBehavior('JBe','application.behavior.JBe');
  3. $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绑定即可