【问题标题】:Symfony2, how to render controller's action in a twig template if controller has a constructorSymfony2,如果控制器有构造函数,如何在树枝模板中呈现控制器的动作
【发布时间】:2015-02-25 09:03:05
【问题描述】:

从官方文档 (http://symfony.com/doc/current/quick_tour/the_view.html#embedding-other-controllers) 我学会了如何在 Twig 模板中嵌入控制器。

Controller 注入属性时出现问题。有没有办法将 Twig 的 render(controller()) 函数与具有构造函数的控制器一起使用?

当我尝试以下操作时:

{{ render(controller(
  'SomeBundle:Some:renderList',
  { 'request': app.request }
)) }}

我收到此错误: Missing argument 1 for SomeBundle\Controller\SomeController::__construct()

此控制器的构造函数如下所示:

public function __construct($container, SomeService $someService) {
  parent::__construct($container);
  $this->someService = $someService;
}

容器和someService的注入在service.yml中配置。

那么,我的问题是:当这个控制器使用依赖注入时,如何将控制器嵌入到 Twig 的模板中?

更新

我可以这样做: {{ render(app.request.baseUrl ~ '/some/route') }} 但我想避免制作路线。

更新 2

来自 service.yml 的服务定义

some.controller:
    class: SomeBundle\Controller\SomeController
    arguments: ["@service_container", "@some.service"]

【问题讨论】:

  • 您是否将控制器正确定义为服务? symfony.com/doc/current/cookbook/controller/…
  • @Smashou 谢谢你的提问。是的,我确实正确地将我的控制器定义为服务。
  • 您可以像 Sylius 项目 (github.com/Sylius/Sylius/blob/master/src/Sylius/Bundle/…) 一样使用像 {{ render(controller('some.controller')) }} 这样的服务名称。尽管我可能错了,但您可能不需要过多地传递请求。
  • 我一定是做错了什么,但我尝试使用 '@' 而没有它,在这两种情况下都会出现此错误:无法解析控制器名称“some.controller”
  • 我强烈建议您不要使用render。它创建了一个子请求,该子请求本身将再次加载全栈框架,从而增加服务器的负载和页面加载时间。您可以创建一个服务(注入 @template)并将其添加到 twig 全局变量并调用它。

标签: symfony dependency-injection twig


【解决方案1】:

如果您已将控制器定义为服务,则需要将其“注入”到 twig 中以使其可用并正确实例化。

我建议创建 twig 全局变量

#app/config/config.yml
twig:
    globals:
        cc: "@comparison.controller"

那么你可以使用其中一种方法(动作?)

{{ cc.foo(aBarVariable) }}

另一种答案

您可以创建一个twig extension,您可以在其中注入您的服务以使其可用于查看

【讨论】:

  • 感谢您的回答。它确实有效。最后一个问题。来自控制器的渲染函数也返回此行:HTTP/1.0 200 OK Cache-Control: no-cache Date: Wed, 25 Feb 2015 09:24:06 GMT。我怎样才能摆脱它?
  • @greg:我有点困惑,什么是“摆脱”?
  • 没关系。我会自己处理。再次感谢您的意见。你帮了忙。
  • 我不得不使用控制器的函数 renderView 而不是 render 来防止缓存头被渲染。以防万一有人遇到同样的问题。
  • 如果你不得不使用 renderView 那你还是有问题。
【解决方案2】:

对于作为服务的控制器,您只需要使用服务名称 (@some.controller) 和操作 (yourAction) 而不是控制器快捷方式 (SomeBundle:Some:renderList),正如您在 Sylius templates 中看到的那样。

原来如此……

{{ render(controller('some.controller:yourAction')) }}

如果您是 Symfony 2.4+,您可以使用 request_stack 来获取请求,而不是将其作为参数传递给......

$request = $this->container->get('request_stack')->getMasterRequest();

【讨论】:

  • 对我来说,它不起作用。我已将控制器定义为服务,但出现以下错误:Unable to parse the controller name "gridview.controller".,其中gridview.controller 是我的服务名称。我在视图中这样调用:{{ render(controller('gridview.controller')) }}
  • 谢谢。但现在我遇到了另一个问题。我的控制器在其构造函数中注入了一个模板引擎。当以这种方式调用时,我收到以下消息:Catchable Fatal Error: Argument 1 passed to GridviewBundle\Widget\Grid::__construct() must implement interface Symfony\Component\Templating\EngineInterface, none given。有什么线索吗?
  • 如果是不同的问题,您应该创建一个新问题。我只能假设您没有在服务定义中注入 @templating 服务,或者在设置控制器时尚未对其进行初始化。
猜你喜欢
  • 2013-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-23
  • 2013-08-07
  • 2023-03-17
  • 2017-01-05
  • 2017-09-30
相关资源
最近更新 更多