Symfony表单:使用参数筛选集合



我使用的是Symfony 3.4。

我有一个表格来编辑特定国家的一些答案,我需要按类别编辑这些答案。

我已经在我的实体中设置了一个过滤器,但我不知道如何用表单中的参数调用这个getter

肮脏的替代方案是从我的控制器中的表单中删除不需要的元素,但这并不理想。。。

这是我的表格:

<?php
namespace cwtpsmdbBundleForm;
use cwtpsmdbBundleEntityCcdbServicesAnswers;
use cwtpsmdbBundleEntitycountries;
use DoctrineORMEntityRepository;
use SymfonyBridgeDoctrineFormTypeEntityType;
use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentOptionsResolverOptionsResolver;
use SymfonyComponentFormExtensionCoreTypeCollectionType;
class countriesCCDBServicesAnswersType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('AnswersOfCategory', CollectionType::class, array(
'entry_type' => CcdbServicesAnswersType::class,
'entry_options' => array('label' => false,),
'label' => false,
));    
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'cwtpsmdbBundleEntitycountries',
'categoryID' => 1,
));
}
/**
* @return string
*/
public function getBlockPrefix()
{
return 'cwt_psmdbbundle_countries';
}
}

这是我的实体:

<?php
namespace cwtpsmdbBundleEntity;
use APYDataGridBundleGridMapping as GRID;
use DoctrineORMMapping as ORM;
/**
* countries
*
* @ORMTable()
* @ORMEntity(repositoryClass="cwtpsmdbBundleEntityRepositorycountriesRepository")
*/
class countries
{
/**
* @var integer
*
* @ORMColumn(name="id", type="integer")
* @ORMId
* @ORMGeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORMColumn(name="code", type="string", length=2)
*/
private $code;
/**
* @var string
*
* @ORMColumn(name="name", type="string", length=100)
*/
private $name;    
/**
* @ORMOneToMany(targetEntity="cwtpsmdbBundleEntityCcdbServicesAnswers", mappedBy="country", cascade={"persist", "remove"})
*/
private $ccdbServicesAnswers;

// Specific Functions
/**
* Get ccdbServicesAnswers.
*
* @return DoctrineCommonCollectionsCollection
*/
public function getAnswersOfCategory($categoryID)
{
return $this->getCcdbServicesAnswers()->filter(function(CcdbServicesAnswers $answer) use($categoryID) {
return $answer->getQuestion()->getCategory()->getId() == $categoryID;
});
}

这是我在控制器中的创建表单函数:

private function createCountryEditForm(Countries $entity, $categoryID)
{
$form = $this->createForm(countriesCCDBServicesAnswersType::class, $entity, array(
'action' => $this->generateUrl('updateCountryCcdbServicesAnswers', array('countryID' => $entity->getId())),
'method' => 'PUT',
'categoryID' => $categoryID,
));
$form->add('submit', submitType::class, array('label' => 'Update', 'attr' => array('class' => 'hidden')));
return $form;
}

[更新日期:2018年11月20日]

以下是我到目前为止所做的。这是可行的,但我更喜欢一个更干净的解决方案,它在数据库级别使用where子句来处理这个过滤器,并且更DRY。在conroller级别上这样做意味着我必须在任何需要这个过滤器的地方都这样做。

private function createCountryEditForm(Countries $entity, $categoryID)
{
$form = $this->createForm(countriesCCDBServicesAnswersType::class, $entity, array(
'action' => $this->generateUrl('updateCountryCcdbServicesAnswers', array('countryID' => $entity->getId(), 'categoryID' => $categoryID)),
'method' => 'PUT',
'categoryID' => $categoryID,
));
$answers = $form->get('ccdbServicesAnswers')->getData();

foreach ($answers as $answer) {
if($answer->getQuestion()->getCategory()->getId() != $categoryID) {
$answers->removeElement($answer);
}
}
$form->get('ccdbServicesAnswers')->setData($answers);
$form->add('submit', submitType::class, array('label' => 'Update', 'attr' => array('class' => 'hidden')));
return $form;
}

您不应该在实体中使用筛选器。您应该使用DQL手动获取答案。获取实体数组并将其传递给具有CollectionType的窗体。

use cwtpsmdbBundleEntityCcdbServicesAnswers;
use cwtpsmdbBundleFormcountriesCCDBServicesAnswersType;
// ....
$queryBuilder = $this->createQueryBuilder()
->select('a')
->from(CcdbServicesAnswers::class, 'a')
->where('
country = :country
AND category = :category
')
->setParameters([
'country' => $country,
'category' => $category
]);
$answers = $queryBuilder->getQuery()->getArrayResult();
$this->createForm(countriesCCDBServicesAnswersType::class, [
'AnswersOfCategory' => $answers
]);

您可以将所需数据的提取封装到存储库中:https://symfony.com/doc/current/doctrine.html#querying-对于对象,存储库

相关内容

  • 没有找到相关文章

最新更新