我正在学习Yii。我有一个测试开发,其中包含许多表(employee,personalDetails,address)。我对MVC的理解使我看到这些几乎是独立的行星,其中每个(MVC)组件在该世界中扮演着明确的角色。
我有一个问题开始让我感到烦恼,因为我现在想要在这些世界之间传递数据和计算请求。我发现了一些关于如何做到这一点的帖子,但它们看起来更像是“黑客”而不是“规定”的做法。我显然不想养坏习惯。这种过程显然是任何开发的根本要求,所以想要就此提出一些指导。
一个具体的例子是返回带回家工资的员工的视图>包括奖金在内的$ 100,000(例如员工控制员要求personalDetails控制器计算{goss salary + bonus- tax}并返回所有适当的实例,然后查找并返回相关员工)。
那么我在personalDetails中创建一个函数并从内部员工控制器中调用它,或者这种事情应该在扩展中进行...还是有另一种方法?
感谢您对此的指导
答案 0 :(得分:4)
对于封装的自我管理视图部分,请使用widgets。对于上述情况,您可以使用可配置的treshhold创建小部件。
如果你不得不要求不同的控制器来计算某些东西,这是一种不好的做法。将此类计算放在模型中。模型具有高度可重用性,视图可以重用,但控制器应该只响应操作并将数据绑定到视图。
胖模型,瘦控制器,智慧视图。
以下是一些草案代码:
首先创建包含任何所需计算的模型:
class Employee extends CActiveRecord
{
public function getTotalSalary()
{
// Do any calculations here
// ...
return $salary;
}
}
然后你可以在控制器中重复使用它:
class FirstController extends CController
{
public function actionPersonDetails()
{
$model = $this->_loadModel();
// By assigning this you will have getTotalSalary() available in view
$this->render('personDetails', ['model' => $model]);
}
}
class SecondController extends CController
{
public function actionViewSallary()
{
$model = $this->_loadModel();
// Also here you will have getTotalSalary() available in view
$this->render('viewSallary', ['model' => $model]);
}
}
对于需要独立创建窗口小部件的更复杂场景:
class EmployeesWidget extends CWidget
{
public $minSalary = 0;
private $_data = null;
public function init()
{
$this->_data = new CActiveDataProvider(/* Criteria here with $this->minSalary as param */);
}
public function run()
{
$this->render('employeesWidget', ['data' => $this->_data]);
}
}
然后您可以在任何视图中轻松使用它,即使在其他小部件中也是如此:
$this->widget('path.to.EmployeesWidget', [
'minSallary' => 10000
]);