在AcmePizza BUndle中这很好用
->add('pizza', 'entity', array(
'class' => 'Acme\PizzaBundle\Entity\Pizza',
'query_builder' => function ($repository) { return $repository->createQueryBuilder('p')->orderBy('p.name', 'ASC'); },
))
我可以在收藏中做类似的事吗
->add('userTasks','collection',array('type' => new UserTaskType(),
'class' => 'acme\myBundle\Entity\UserTask',
'query_builder' => function ($repository) { return $repository->createQueryBuilder('p')->orderBy('p.name', 'ASC'); },
))
答案 0 :(得分:4)
假设您的userTasks是一种关系您将找到您的案例here的答案。这些只是如何排序,但如果你需要一些WHERE条件,它不是那么简单但不是很难。
我必须过滤掉一些实体,解决它的关键是在实体类中创建返回所需集合的set / get方法。
就我而言,它看起来像这样
/**
* Set values
*
* @param ArrayCollection $values
* @return Attribute
*/
public function setCustomValues($values)
{
$result = $this->getNotCustomValues();
foreach ($values as $value)
{
$value->setAttribute($this);
$result->add($value);
}
$this->values = $result;
return $this;
}
/**
* Get values
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getCustomValues()
{
$result = new ArrayCollection();
foreach ($this->values as $value) {
if($value->getCustom()) {
$result->add($value);
}
}
return $result;
}
在创建表单时,字段的名称是“customvalues”而不是“values” 所以我的集合只包含自定义字段为true的值。
答案 1 :(得分:1)
您经常希望在更新实体时过滤集合,而不是新实体,对吗?
这是一个有效的解决方案,这是来自控制器(CRUD)的一个例子:
public function updateAction($id)
{
$service = $this->getServiceRepository()->loadOne('id', $id);
$this->checkPermission($service);
$this->filterInventoryByPrimaryLocation($service);
if($this->getFormHandler()->process('service_repair_service', $service, array('type' => 'update')))
{
$this->getEntityManager()->process('persist', $service);
return $this->render('ServiceRepairBundle:Service:form_message.html.twig', [
'message' => $this->trans('Service has been updated successfully.')
]);
}
return $this->render('ServiceRepairBundle:Service:form.html.twig', [
'form' => $this->getFormHandler()->getForm()->createView(),
]);
}
private function filterInventoryByPrimaryLocation(Service $service)
{
$inventory = $service->getInventory();
$criteria = Criteria::create()
->where(Criteria::expr()->eq('location', $this->getUser()->getPrimaryLocation()))
->orderBy(array('timeInsert' => Criteria::ASC));
$service->setInventory($inventory->matching($criteria));
}
$ service = ENTITY, $ inventory = ArrayCollection($ service-> getInventory())
这里的关键是使用Doctrine的标准,更多信息在这里:
还要考虑在实体本身移动Criteria,在那里制作一个公共方法。从数据库加载时,可以使用doctrine的postLoad生命周期回调来触发该方法。如果你不需要任何服务或类似的东西,那么把它放在实体中就会有效。
另一种解决方案可能是,如果您只需要在表单内部进行过滤,则可以在Form类中的Form事件中移动Criteria。
如果您需要在整个项目中透明地完成集合过滤,请编写一个doctrine侦听器并将代码放在postLoad()方法中。你也可以在doctrine listener中注入依赖项,但我建议注入容器本身,因为延迟加载其他服务,所以你不会得到循环服务引用。
祝你好运!答案 2 :(得分:0)
我指出你正确的方向(我希望):
http://www.craftitonline.com/2011/08/symfony2-ajax-form-republish/
本文讨论字段依赖性。例如,当您选择国家/地区时,您拥有属于列表中显示的国家/地区的城镇。
答案 3 :(得分:-1)
在Symfony 2.7中,我通过在 UserTaskType 中执行以下操作解决了这个问题:
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Doctrine\ORM\EntityRepository;
class UserTaskType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('the_name', 'entity', array(
'class' => 'acme\myBundle\Entity\UserTask',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u')
->where('u.id > :id')
->setParameter('id', '1')
->orderBy('u.username', 'ASC');
},
));
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'acme\myBundle\Entity\UserTask',
));
}
}
答案 4 :(得分:-2)
是
在UserTaskType类中,添加以下方法。
public function getDefaultOptions(array $options)
{
return array(
'data_class' => 'acme\myBundle\Entity\UserTask',
'query_builder' => function($repo) {
return $repo->createQueryBuilder('p')->orderBy('p.name', 'ASC');
}
);
}