13

在 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'); },
                ))
4

5 回答 5

4

假设您的 userTasks 是一种关系,您将在此处找到您的案例的答案。这些只是如何排序,但如果您需要一些 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 的值。

于 2013-06-07T03:35:45.357 回答
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's Criteria,更多信息在这里:

http://doctrine-orm.readthedocs.org/en/latest/reference/working-with-associations.html#filtering-collections

还可以考虑将 Criteria 移动到实体本身,在那里创建一个公共方法。当您从数据库加载它时,您可以使用学说的 postLoad 生命周期回调触发该方法。如果您不需要任何服务或类似的东西,当然将其放入实体中会起作用。

如果您只需要在表单内进行过滤,则另一种解决方案可能是在 Form 类内的 Form Event 中移动 Criteria。

如果您需要在整个项目中透明地完成集合过滤,请编写一个学说监听器并将代码放在 postLoad() 方法中。您也可以在学说监听器中注入依赖项,但我建议注入容器本身,因为延迟加载其他服务,所以您不会得到循环服务引用。

祝你好运!

于 2014-05-05T16:12:29.910 回答
0

我指出你正确的方向(我希望):

http://www.craftitonline.com/2011/08/symfony2-ajax-form-republish/

本文处理字段依赖关系。例如,当您选择一个国家/地区时,您将拥有属于该国家/地区的城镇出现在列表中。

于 2012-08-12T19:11:16.233 回答
-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',
        ));
    }

}
于 2017-04-11T08:44:15.943 回答
-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');
        }
    );
}
于 2012-08-07T00:18:32.450 回答