我正在制作广告页面。广告可以是不同类型的,因此具有不同的数据。例如,车辆将make
和model
作为额外数据。
现在,我有一个基本学说实体Advert
,其中包含每个广告所需的数据。不同的广告反过来依旧存在这些数据(doctrine2 discriminatormap)
如果用户选择创建车辆广告,我需要动态填充表单(使用ajax和symfony2表单)我想显示车辆广告的选项。但我还需要将实体更改为AdvertVehicle
形式。
这可能吗?我确实在symfony2主页上阅读了食谱条目
“如何使用表单事件动态修改表单”: 这应该通过向您的应用程序发回AJAX来处理。在该控制器中,您可以提交表单,但只需使用提交的表单呈现更新的字段,而不是处理它。然后可以使用AJAX调用的响应来更新视图。
我理解如何将ajax调用回我的控制器,并且我理解如何使用表单事件但是如何获得渲染的选择框(例如包含车辆模型)的响应?使用新的AbstractType?还是formbuilder?
然后,当用户实际提交表单时,我需要使用所选广告类型的实体。我可以根据表单中的用户选择动态更改实体吗?
修改
我检查了表格遗传,这很好,谢谢。我扩展了AdvertType
并覆盖了buildForm()
方法,在我添加AdvertVehicleType
所需的项目之前,我调用了父方法。
其他解释
每个广告实体都包含price
,description
,title
和category
。某些广告包含更多广告,例如make
和model
。它们由discriminatormap
(doctrine2)
示例:
// -- Entity
class CarAdvert extends Advert {
protected $model;
protected $make;
}
// -- Entity
// -- This uses discriminator mapping
class Advert {
protected $title;
protected $description;
protected $price;
protected $category;
}
如果用户选择类别cars
我想使用CarAdvert
实体(用于验证和持久性),如果用户选择了house hold itemcategory,我只想使用普通{{1}实体。
一个主要问题仍然是我无法弄清楚如何通过ajax呈现扩展表单。关于这一部分的任何提示?当用户选择汽车作为类别时,我希望更新表单(通过jQuery / ajax)但是如何创建一个只检索表单扩展部分的控制器并将html作为响应发送回来(不使用twig)并在视图中呈现它,这可能吗?
解决方案:
见下面的答案!
答案 0 :(得分:2)
<强>解决方案:强>
我的问题的解决方案是在控制器中创建一些额外的功能,以解决我希望能够从用户的选择中“动态”更改实体和形式的问题。
public function indexAction(Request $request)
{
$form = $this->getForm($request);
$form->handleRequest($request);
return array(
'form' => $form->createView(),
'request' => $request->request,
);
}
getForm
检索表单的位置,(例如,车辆的AdvertVehicleType或“默认”广告的AdvertType)。
getForm
方法如下所示:
private function getForm(Request $request)
{
$categoryTitle = 'NONE';
$categoryId = $request->request->get('advert', false)['category'];
if ($categoryId) {
$categoryTitle = $this->getDoctrine()->getRepository('Bundle:Category')->find($categoryId)->getTitle();
}
return $this->createForm($this->getFormType($categoryTitle), $this->getEntity($categoryTitle));
}
这里我检索categoryID
(在请求中的表单中选择)并使用getFormType和带有getEntity的实体检索formType。
private function getEntity($categoryTitle)
{
$entity = new Advert();
switch ($categoryTitle) {
case Category::CARS:
$entity = new AdvertCar();
}
return $entity;
}
private function getFormType($categoryTitle)
{
switch ($categoryTitle) {
case Category::CARS:
return new AdvertCarType();
default:
return new AdvertType();
}
}
为了能够使用ajax“动态”更新这个(但是如果用户尝试提交表单,它也可以工作)我在控制器中创建了另一个动作。
这个动作呈现了我要更新的表单部分(在ajax调用中),我通过实际选择表单中使用twig设置表单对象来呈现我不需要的内容,如下所示:< / p>
{% do form.title.setRendered %}
(这只是我实际上对所有我不想渲染的表单对象执行此操作的示例。
然后我只是打电话:
{{ form_rest(form) }}
将检索表单的“rest”,这对于不同的类别是不同的。
现在让我们说你有州和城镇可供选择。首先选择状态,然后在树枝中渲染该状态的城镇(但实际上你可以只渲染你需要的部分,例如{{ form_row(form.towns) }}
,然后将这个渲染模板作为json响应返回并将其放入用jquery你想要的div。
$html = $this->renderView('@Bundle/NewAddPage/filter_area.twig', array('form' => $form->createView()));
然后在响应中返回$ html变量。
我希望这会有所帮助,而且解释已经足够好了,如果不只是发表评论,我会用我的答案更新这个!