1

我的应用程序中的大多数控制器都有一个基本控制器,如下所示:

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 }  %}

我对这种方法的问题是:

  1. 每个需要成为部分控制器的动作都必须有一个$partial参数。由于大多数动作都有可能是局部的,因此所有控制器都必须撒上它。
  2. 每个潜在的部分动作都必须有$this->partial = $partial线条,很容易忘记。

通过使用一些 Symfony 或 Twig 魔法(覆盖render标签等),它有一种更清洁的方式。为了摆脱上述问题?

4

2 回答 2

0

我已经覆盖了大多数控制器中的渲染方法,以便将一些标准变量注入我的模板中。它似乎工作得很好,但它所做的只是让从控制器渲染模板更容易一些,因为你不必显式地将 $this 传递给模板。

我不太确定将引用传递给控制器​​是否是个好主意。至少对于您的示例,仅传递部分似乎就是您所需要的。

您真的需要为您的模板提供这种部分功能吗?似乎更容易只有两个模板(一个用于页面,一个用于部分)。但也许您的用例需要它。

于 2012-05-18T11:51:28.927 回答
0

经过一些研究和内部挖掘,我想出了一个优雅的解决方案。

答案是构建一个事件监听器(在Symfony2 Docs中有介绍)。更准确地说:一个控制器监听器,类的内容如下所示。这允许对部分进行透明处理,而无需对控制器代码进行任何更改。

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);
    }
}
于 2012-05-22T06:54:05.580 回答