Symfony 嵌入式控制器形式

Symfony embedded controller form

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

/list-view/{city}/{category}?q=searchQuery

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

非常感谢和问候 拉斐尔

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

可以通过多种方式执行重定向,例如 return 一些 JS 脚本代码进行重定向(恕我直言,这非常丑陋)。我不会使用来自 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);
}

你的Controller.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 }}