我的应用程序中的大多数控制器都有一个基本控制器,如下所示:
class BaseController extends \Symfony\Bundle\FrameworkBundle\Controller\Controller
{
/**
*
* @Route("/")
*/
public function indexAction($partial = false)
{
$this->partial = $partial;
$this->currentAction = 'index';
return $this->r();
}
}
这附带一组模板,可以是带有布局的完整html页面,也可以只是内容。这是通过模板中的一行完成的:
{% extends this.partial ? "SomeProject:_base:partial.html.twig" : "SomeProject::layout.html.twig" %}
(其中this
是控制器参考)。
然后可以在其他控制器中呈现这些模板,而无需通过布局重复布局。
{% render 'SomeProject:SomeController:index' with { "partial":true } %}
我对这种方法的问题是:
$partial
个参数。由于大多数动作都有可能是部分动作,因此所有控制器都必须随附。$this->partial = $partial
行,这很容易被遗忘。通过使用一些Symfony或Twig魔法(覆盖render
标签等)有一种更清洁的方式。为摆脱上述问题?
答案 0 :(得分:0)
我已经在大多数控制器中覆盖了渲染方法,以便将一些标准变量注入到我的模板中。它似乎运行良好,但它将为您做的一切将是从控制器渲染模板更容易,因为您不必显式地将$ this传递给模板。
我不太确定传递对控制器的引用是个好主意。至少在你的例子中,只是传递部分似乎就是你所需要的。
你真的需要为你的模板提供这种部分功能吗?似乎更容易只有两个模板(一个用于页面,一个用于部分)。但也许你的用例需要它。
答案 1 :(得分:0)
经过一些研究和在内部挖掘后,我提出了一个优雅的解决方案。
答案是构建一个事件监听器(在Symfony2 Docs中)。更确切地说:一个控制器监听器,其中的类似于下面的内容。这允许透明地处理partial而不对Controller代码进行任何更改。
class ControllerListener
{
/**
*
* @param BaseController $ctrl
* @param Request $request
* @return BaseController
*/
public function injectPartial($ctrl,Request $request)
{
if ($ctrl instanceof BaseController)
{
if ($request->get("partial",false))
$ctrl->setPartial($request->get ("partial"));
}
return $ctrl;
}
public function onKernelController(FilterControllerEvent $event)
{
$ctrl = $event->getController();
$ctrl[0] = $this->injectPartial($ctrl[0], $event->getRequest());
$event->setController($ctrl);
}
}