3

我已经用 Yii 玩了几个月了,为了以 Yii 的方式构建代码,我想知道如何最好地让模型成为其他模型的列表。

Yii 在概念上似乎有非常接近 DAO 的模型,而 MVC 设计推动不要将非 DAO 模型放在模型之外的任何地方。(我不是 MVC 专家)

2个原因,列表很好:

  • 我正在寻找像CModelList这样的东西来扩展当对象具有相当数量的逻辑而无法通过关系处理时(无论如何这是一个 CActiveRecord 元素)
  • 列表作为一种类型可以将逻辑应用于元素,而不必一次将它们全部加载到内存中,并且仍然提供单一类型以在具有ids 的代码中使用并仅加载子集

什么似乎没有解决问题

  • 关系活动记录:因为并非所有模型都是活动记录
  • 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 中是否缺少它,我应该开始以不同的方式思考,或者使用和保持干净代码和结构的机制是什么?

4

1 回答 1

2

组件行为的使用

一个组件支持mixin模式并且可以附加一个或多个行为。行为是一个对象,其方法可以通过收集功能而不是专门化(即普通类继承)的方式由其附加组件“继承”。一个组件可以附加多个行为,从而实现“多重继承”。

行为类必须实现IBehavior接口。大多数行为都可以从CBehavior基类扩展。如果需要将行为附加到模型,它也可以从CModelBehaviorCActiveRecordBehavior扩展,后者实现了特定于模型的附加功能。

要使用行为,必须首先通过调用行为的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();

附加到同一组件的两个行为可能具有相同名称的方法。在这种情况下,第一个附加行为的方法将优先。

当与事件一起使用时,行为更加强大。一个行为,当被附加到一个组件时,可以将它的一些方法附加到组件的一些事件上。通过这样做,行为有机会观察或改变组件的正常执行流程。

行为的属性也可以通过它所附加的组件来访问。属性包括公共成员变量和通过行为的 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/

于 2012-06-20T06:34:34.287 回答