Symfony嵌入式控制器表

时间:2015-04-23 18:53:32

标签: php forms symfony twig

我有一个带有一些选择框的搜索表单。我使用嵌入式控制器在每个页面的headnavi中渲染它。 (http://symfony.com/doc/current/book/templating.html#embedding-controllers) 我想使用表单输出重定向到我的列表视图页面,如下所示:

  

/列表视图/ {城市} / {类别} Q = SEARCHQUERY

当我通过路线呼叫控制器时,我的表格和请求运行良好,但不幸的是,当我嵌入控制器时,我遇到了两个问题。就像我在这里阅读(Symfony 2 - Layout embed "no entity/class form" validation isn't working)一样,由于子请求,我的请求并没有被我的表单所取代。答案中有一个解决方案,但不是很详细。 修复第一个问题后,另一个问题是我无法从嵌入式控制器(Redirect from embedded controller)进行重定向。 也许任何人都有一个更简单的解决方案,在每个页面上都有一个表单,可以让我重定向到它的数据?

非常感谢和问候 圣拉斐尔

1 个答案:

答案 0 :(得分:1)

Symfony 2 - Layout embed "no entity/class form" validation isn't working的答案100%正确,但我们使用上下文并将它们隔离,因此始终使用主请求的操作会破坏规则。您拥有request_stack中的所有请求(一个主要和零个或多个子请求)。向控制器操作中注入Request $request是当前请求,即只有max=3的子请求(现在不推荐注入Request)。因此,你必须使用正确的'请求。

执行重定向可以通过多种方式完成,例如返回一些JS脚本代码来重定向(这是非常丑陋的imho)。我不会使用twig的子请求,因为它开始重定向已经太晚了,但是在动作中进行子请求。我没有测试代码,但它应该工作。 Controller::forward是您的朋友,因为它会复制当前执行子请求的请求。

Controller.php(只是为了查看实现)。

/**
 * Forwards the request to another controller.
 *
 * @param string $controller The controller name (a string like BlogBundle:Post:index)
 * @param array  $path       An array of path parameters
 * @param array  $query      An array of query parameters
 *
 * @return Response A Response instance
 */
protected function forward($controller, array $path = array(), array $query = array())
{
    $path['_controller'] = $controller;
    $subRequest = $this->container->get('request_stack')->getCurrentRequest()->duplicate($query, null, $path);
    return $this->container->get('http_kernel')->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
}

<强> YourController.php

public function pageAction() {
  $formResponse = $this->forward('...:...:form'); // e.g. formAction()
  if($formResponse->isRedirection()) {
    return $formResponse; // just the redirection, no content
  }
  $this->render('...:...:your.html.twig', [
    'form_response' => $formResponse
  ]);
}

public function formAction() {
  $requestStack = $this->get('request_stack');
  /* @var $requestStack RequestStack */

  $masterRequest = $requestStack->getCurrentRequest();
  \assert(!\is_null($masterRequest));

  $form = ...;
  $form->handleRequest($masterRequest);

  if($form->isValid()) {
    return $this->redirect(...); // success
  }

  return $this->render('...:...:form.html.twig', [
    'form' => $form->createView()
  ]);
}

<强> your.html.twig

{{ form_response.content | raw }}