我已经使用 Yii 几个月了,为了按照 Yii 的方式构建代码,我想知道如何最好地让模型成为其他模型的列表。
Yii 的模型在概念上似乎非常接近 DAO,而 MVC 设计插入不要将非 DAO 模型放在模型以外的任何地方。 (我不是 MVC 专家)
2 个原因,列表很好:
- 我正在寻找类似 CModelList 的东西来扩展当对象具有相当多的逻辑而无法用 relations 处理时(无论如何都是 CActiveRecord 元素)
- 作为一种类型的列表可以将逻辑应用于元素,而不必一次将它们全部加载到内存中,并且仍然提供单一类型以在代码中使用 ids 并仅加载子集<
什么好像没有解决问题
- Relational Active Record : 因为不是所有模型都是事件记录
- CAttributeCollection : 因为它只支持内存中的所有对象,比如数组
- 不同模型中的相同方法,例如 getRestaurantsAverageRatingByPriceRange:因为这是 OOP 中的函数式编程,随着模型拥有更多方法而迅速增长
示例 1
$user = User::model()->findByPk($userID); // get a user
$restaurantList = $user->getRestaurants(); // get restaurants for that user
for($i=0;$i<5;$i++) {
$this->renderPartial( "rating",
array("rating" => $restaurantList->getAverageRatingByPriceRange( $i ) );
}
示例 2(相同的列表逻辑,不同的基础模型)
$city = City::model()->findByPk($cityID); // get a city
$restaurantList = $city->getRestaurants(); // get restaurants for that city
for($i=0;$i<5;$i++) {
$this->renderPartial( "rating",
array("rating" => $restaurantList->getAverageRatingByPriceRange( $i ) );
}
示例 3(相同的列表类型和基本模型,不同的逻辑)
$user = User::model()->findByPk($userID); // get a user
$restaurantList = $user->getRestaurants(); // get restaurants for that user
$this->renderPartial( "map",
array("coord" => $restaurantList->getCoordinatesMap() );
那么 Yii 中是否缺少它,我应该开始换个思路,还是应该使用什么机制来保持干净的代码和结构?
最佳答案
组件行为的使用
一个组件支持 mixin模式,并且可以附加一种或多种行为。行为是一个对象,其方法可以通过收集功能而不是专门化(即普通类继承)的方式由其附加组件“继承”。一个组件可以附加多个行为,从而实现“多重继承”。
行为类必须实现IBehavior
接口(interface)。大多数行为都可以从 CBehavior
基类扩展。如果需要将行为附加到模型,它也可以从 CModelBehavior 扩展或 CActiveRecordBehavior它实现了特定于模型的附加功能。
要使用行为,必须首先通过调用行为的 attach()
方法将其附加到组件。然后我们可以通过组件调用行为方法:
// $name uniquely identifies the behavior in the component
$component->attachBehavior($name,$behavior);
// test() is a method of $behavior
$component->test();
可以像访问组件的普通属性一样访问附加行为。例如,如果一个名为 tree 的行为附加到一个组件,我们可以使用以下方法获取对该行为对象的引用:
$behavior=$component->tree;
// equivalent to the following:
// $behavior=$component->asa('tree');
可以暂时禁用一个行为,这样它的方法就不能通过组件使用。例如,
$component->disableBehavior($name);
// the following statement will throw an exception
$component->test();
$component->enableBehavior($name);
// it works now
$component->test();
附加到同一组件的两个行为可能具有相同名称的方法。在这种情况下,第一个附加行为的方法将优先。
与events一起使用时,行为更加强大。一个行为,当被附加到一个组件上时,可以将它的一些方法附加到组件的一些事件上。通过这样做,行为有机会观察或改变组件的正常执行流程。
行为的属性也可以通过它所附加的组件来访问。这些属性包括公共(public)成员变量和通过行为的 getter 和/或 setter 定义的属性。例如,如果一个行为有一个名为 xyz 的属性,并且该行为附加到组件 $a。然后我们可以使用表达式 $a->xyz
来访问行为的属性。
更多阅读:
http://www.yiiframework.com/wiki/44/behaviors-events
http://www.ramirezcobos.com/2010/11/19/how-to-create-a-yii-behavior/
关于php - Yii 到 CModel 列表的方式是什么(其他 CModel 列表与否)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7085480/