Passing values between controllers

2020-04-30 10:11发布

问题:

I'm learning Yii. I have a test development which contains a number of tables (employee, personalDetails, address). My understanding of MVC leads me to see these almost as individual planets, where each (MVC) component plays a clearly defined role within that world.

I have a question that’s starting to bug me because I now want to pass requests for data and calculations between these worlds. I have come across a few postings on how to do this, but they appear more like “hacks” than “prescribed” practises. I’m obviously keen not to pick up bad habits. This kind of process is obviously a root requirement of any development so would like to ask for some guidance on this.

A specific example would be to return a view of employees who have take home salaries > $100,000 including bonuses ( e.g. employee controller asks personalDetails controller to calculate {goss salary + bonuses – tax} and return all appropriate instances, it then looks up and returns the relevant employees).

So do I create a function in personalDetails and call it from inside employee controller, or should this kind of thing go in an extension ... or is there another approach?

I’d appreciate your guidance on this

回答1:

For encapsulated self managed view parts use widgets. For above case you could create widget with configurable treshhold.

If you have to ask different controller to calculate something it is a bad practice. Place such calculations in model instead. Model is highly reusable, view can be reused, however controller should only respond to action and bind data to view.

Fat model, thin controller, wise view.

Here is some draft code:

First create model with any needed calculations:

class Employee extends CActiveRecord
{
    public function getTotalSalary()
    {
        // Do any calculations here
        // ...
        return $salary;
    }
}

Then you can reuse it in controllers:

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]);
    }
}

And for more complex scenarios where you need something standalone create widget:

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]);
    }
}

Then you can easy use it in any view, even in other widgets:

$this->widget('path.to.EmployeesWidget', [
    'minSallary' => 10000
]);


标签: php yii