event and behavior

When used together with events, behaviors are even more powerful. A behavior, when being attached to a component, can attach some of its methods to some events of the component. By doing so, the behavior gets a chance to observe or change the normal execution flow of the component.

很是不能理解:A behavior, when being attached to a component, can attach some of its methods to some events of the component。行为可以绑定它的一个方法到component的事件上去?

特别是event,我也不是很懂,有哪里用,什么时候用?不太清楚……

相关的文档也看了 :-[

behavior是用来扩展CComponent的功能的,比如

$component-> attachBehavior (‘foo’,$b)

$b是个实现了IBehavior接口的behavior,如果 $b有个方法 hello(), 那么Component可以直接调用

$component->hello();

behavior的功能大概我可以理解,楼上能举些event的例子吗?谢谢

行为和事件单独的使用,是能够理解的;可是文档说:可以把行为绑定到组件事件上,那么行为就有机会去观察和改变组件的执行流程。

如果理解没有错误的话,那么1)怎样实现行为和事件的绑定(这里是非常迷惑的);2)这种绑定在何种场景下显得非常有用;

楼上又把问题抛给我了。 :unsure:

通常情况下是:给component注册event,绑定behavior,但文档所说的behavior与event的attache确实很让人费解;

看看Yii.base.CComponent类,我也看得不是很懂……^_^

建议看看zii里的CTimestampBehavior (最好也看看相关的基类CBehavior和CComponent)

“把行为绑定到组件事件上”这个在CModel上用了

CModel的validate方法里:




if($this->beforeValidate())

{

	foreach($this->getValidators() as $validator)

		$validator->validate($this,$attributes);

	$this->afterValidate();

	return !$this->hasErrors();

}



可以看到在调用validator的validate方法前后,定义了两个事件触发点:onBeforeValidate 和 onAfterValidate

现在我们可以在onBeforeValidate 事件上注册自己的回调函数,这样在调用每个校验器之前有个机会来处理model数据了

注册回调函数一个做法是: $model->onBeforeValidate=$callback;

$callback 需要是个全局函数或是个对象的方法,很简单,问题是我们需要自己来创建这个全局函数或对象!而这是我们要尽量避免的东西!

Yii提供了“把行为绑定到组件事件上”

CBehavior类里有个方法




	public function events()

	{

		return array();

	}



就是把自身自动注册到events数组里表示的组件的事件里

看看 CModelBehavior 里的实现:




class CModelBehavior extends CBehavior

{


	public function events()

	{

		return array(

			'onBeforeValidate'=>'beforeValidate',

			'onAfterValidate'=>'afterValidate',

		);

	}




	public function beforeValidate($event)

	{

	}




	public function afterValidate($event)

	{

	}

}



即CModelBehavior的子类会把自己的beforeValidate和afterValidate方法注册到组件(CModel)的onBeforeValidate和onAfterValidate事件里。

例子:




class LoginForm extends CFormModel

{

	public $username;

	public $password;

	public $rememberMe;




	

	public function behaviors()

	{

		return array(

		'FormBehavior'=>array('class'=>'AllFieldsRequired'));

	}

}


class AllFieldsRequired extends CModelBehavior

{

	public function beforeValidate($event)

	{

		$form = $event->sender;

		foreach($form->getAttributes() as $name => $value)

		{

			if($value == '')

			{

				$form->addError($name,"$name cannot be blank!!");

			}

		}

		$event->isValid = !$form->hasErrors();

	}

}



现在我们就把AllFieldsRequired这个行为绑定到了LoginForm的onBeforeValidate事件上了!

very good.

有更好的,实用的场景分析就更好了。 B)

顶个帖子,希望有一个实例场景来说一下best practise!

懂了一点点。如果有更多更详细的例子就好了。