我在里面有名为
dashboard
和PlanningController
的模块。控制器变得太大了,我想把它分成几个单独的控制器。
现在我在
PlanningController
中有以下操作:
/dashboard/planning/purchase
/dashboard/planning/purchase-create
/dashboard/planning/purchase-update
/dashboard/planning/supplier
/dashboard/planning/supplier-create
/dashboard/planning/supplier-update
但我想有 2 个单独的控制器
PurchaseController
和 SupplierController
它们将在逻辑上组合到一个文件夹中planning
:
/dashboard/planning/purchase
/dashboard/planning/purchase/create
/dashboard/planning/purchase/update
/dashboard/planning/supplier
/dashboard/planning/supplier/create
/dashboard/planning/supplier/update
我读到 Yii2 不支持控制器中的子文件夹。如何将两个控制器合并到一个文件夹中?
根据您想要实现的目标,有多种方法可以解决这个问题。
您可以使用 嵌套模块 来构建您的代码。在
planning
中创建一个 modules/dashboard/modules
子模块。然后在仪表板的Module
类中添加嵌套模块,例如:
namespace app\modules\dashboard;
use app\modules\dashboard\modules\planning\Module as PlanningModule;
use yii\base\Module as BaseModule;
class Module extends BaseModule
{
public function init()
{
parent::init();
$this->modules = [
'planning' => [
'class' => PlanningModule::class,
],
];
}
}
这样你就可以将与你的规划控制器相关的所有代码分离到它自己的子模块中。此外,它将帮助您避免路线中的任何潜在冲突。
yii\base\Module::$controllerMap
允许您使用与默认的 yii 命名和文件夹结构约定不匹配的控制器。有了它,您可以将PurchaseController
和SupplierController
放入文件夹modules/dashboard/controllers/planning
中,然后像这样在模块类中设置地图:
namespace app\modules\dashboard;
use app\modules\dashboard\controllers\planning\PurchaseController;
use app\modules\dashboard\controllers\planning\SupplierController;
use yii\base\Module as BaseModule;
class Module extends BaseModule
{
public $controllerMap = [
'purchase' => PurchaseController::class,
'supplier' => SupplierController::class,
];
}
如果您使用这种方法并且希望路由包含“/planning/”部分,您将必须设置特定的 url 规则。
如果你只想拆分
PlanningController
的代码,因为它变得太大了,但你可以将它保留为单个控制器。您可以将操作代码提取到 standalone action classes。
例如,您可以在 PurchaseCreateAction
文件夹中创建 modules/dashboard/controllers/actions/planning
类,如下所示:
namespace app\modules\dashboard\controllers\actions\planning;
use yii\base\Action;
use yii\web\Response;
class PurchaseCreateAction extends Action
{
// string because we will return rendered form view and
// Response because we will return redirect after successful create
public function run(): string|Response
{
// ... action logic
// to redirect
return $this->controller->redirect(...);
// to render view
return $this->controller->render(...);
}
}
您可以像这样在规划控制器中包含独立操作:
namespace app\modules\dashboard\controllers;
use app\modules\dashboard\controllers\actions\planning\PurchaseCreateAction;
use yii\web\Controller;
class PlanningController extends Controller
{
public function actions()
{
return [
'purchase-create' => PurchaseCreateAction::class,
// ... other actions
];
}
}