主题的快速解释:
A"项目"可以有几个"活动"
我必须同时创建尽可能多的"活动"根据需要(你点击一个按钮"添加一个活动"你有一个新的线,这意味着一个新的活动)。我设法通过在我的领域进行收藏来做到这一点。
这是formBuilder的代码:
namespace CoreBundle\Form\Type;
use CoreBundle\Entity\Activities;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class CreateNewActivitiesType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add(
'aeAmount',
CollectionType::class,
array(
'entry_type' => TextType::class,
'allow_add' => true,
'allow_delete' => true,
'label' => 'Montant de l\'AE',
'label_attr' => array(
'class' => 'aeAmount visuallyhidden'
),
'entry_options' => array(
'attr' => array(
'placeholder' => '80 000 €'
),
),
'required' => true
)
)
->add(
'amountSpent',
CollectionType::class,
array(
'entry_type' => TextType::class,
'allow_add' => true,
'allow_delete' => true,
'label' => 'RDP : ',
'label_attr' => array(
'class' => 'amountSpent visuallyhidden'
),
'entry_options' => array(
'attr' => array(
'placeholder' => '35 000 €'
)
),
'required' => true,
)
)
->add(
'afName',
CollectionType::class,
array(
'entry_type' => TextType::class,
'allow_add' => true,
'allow_delete' => true,
'required' => true,
'label' => 'AF : ',
'label_attr' => array(
'class' => 'afName visuallyhidden',
),
'entry_options' => array(
'attr' => array(
'placeholder' => 'AERT-496'
)
)
)
)
->add(
'year',
CollectionType::class,
array(
'entry_type' => TextType::class,
'allow_delete' => true,
'allow_add' => true,
'required' => true,
'entry_options' => array(
'attr' => array(
'readonly' => true
)
),
'label' => 'Année : ',
'label_attr' => array(
'class' => 'year visuallyhidden'
)
)
)
;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'CoreBundle\Entity\Activities'
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'corebundle_collection_activities';
}
}
(我知道我可以做得更短,但重构将会更晚。)
所以,这个目前正在使用,他的相关控制器可以添加我的活动,这里是:
/**
* @param integer $projectId
* @param string $projectType
* @param integer $rdId
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function createNewActivityAction($projectId, $projectType, $rdId)
{
$activity = new Activities();
$request = $this->get('request_stack')->getCurrentRequest();
$form = $this->createForm(CreateNewActivitiesType::class, $activity);
$form->handleRequest($request);
$em = $this->getDoctrine()->getManager();
if ($form->isSubmitted() && $form->isValid()) {
$rdAffiliated = $em->getRepository('CoreBundle:DecisionStatement')->findOneBy(['id' => $rdId]);
$formData = $form->getData();
$yearList = $formData->getYear();
$aeAmountList = $formData->getAeAmount();
$afNameList = $formData->getAfName();
$amountSpentList = $formData->getAmountSpent();
for ($i = 0; $i < count($yearList); $i++) {
$yearDatetime = new DateTime($yearList[$i] . '-01-01 00:00:00');
$existingActivity = $em->getRepository('CoreBundle:Activities')->getExistingActivityWithoutIdentifier(
$yearDatetime,
$rdAffiliated
);
if ($existingActivity) {
/**
* @var Activities $currentActivity
*/
$currentActivity = $existingActivity[0];
$currentActivity->setAeAmount(
$currentActivity->getAeAmount() + $aeAmountList[$i]
);
$currentActivity->setAmountSpent(
$currentActivity->getAmountSpent() + $amountSpentList[$i]
);
$em->persist($currentActivity);
} else {
$newActivity = new Activities();
$newActivity->setYear($yearDatetime)
->setAeAmount($aeAmountList[$i])
->setAfName($afNameList[$i])
->setAmountSpent($amountSpentList[$i])
->setAfReception(false)
->setDecisionStatement($rdAffiliated)
->setPeopleByMonth(0);
$em->persist($newActivity);
}
}
$em->flush();
return $this->redirectToRoute('rd_show_activities', array(
'rdId' => $rdId,
'projectType' => $projectType,
'projectId' => $projectId
));
}
return $this->render('@Core/html/13-edit-activite.html.twig', array(
'page' => 'activities_creation',
'createActivitiesForm' => $form->createView(),
'projectParentId' => $projectId,
'projectParentType' => $projectType,
'rdId' => $rdId
));
}
以下是提交活动表格时var_dump的屏幕截图:
但是我的问题在哪里开始,就是我想要编辑的时候,因为我的表单基于实体&#34;活动&#34;。但我想编辑所有现有的&#34;活动&#34;对于给定的项目,我将有一个包含我的&#34;活动&#34;对象(由findBy方法找到),所以我不能将我的数组传递给我的表单,这会导致错误。 如何转换这些数组&#34;活动&#34;对象只进入一个&#34;活动&#34;对象
答案 0 :(得分:0)
我不明白为什么你只有一个对象&#34;活动&#34;包含几个集合。 您应该创建一个包含多个活动的对象活动。 每个活动只有一个属性&#34;年&#34;,&#34; amountSpent&#34; ... 当你编辑你的对象&#34; ActivitieS&#34;使用适当的表单,您将能够编辑与此对象链接的每个活动。
答案 1 :(得分:0)
要正确管理此类问题,您需要在Symfony中构建Collection of forms。
- “项目”可以有多个“活动”
- 我必须同时创建所需数量的“活动” [...]
醇>
首先,您需要构建一个 Project 实体,该实体将包含所有 Activities 作为Doctrine ArrayCollection,如下所示:
的的src /的appbundle /实体/ Project.php 强>
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
class Project
{
protected $activities;
public function __construct()
{
$this->activities = new ArrayCollection();
}
public function getTags()
{
return $this->tags;
}
}
的的src /的appbundle /窗体/类型/ ProjectType.php 强>
namespace AppBundle\Form\Type;
use AppBundle\Entity\Project;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
class ProjectType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('tags', CollectionType::class, array(
'entry_type' => ActivitiesType::class,
'allow_add' => true,
));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Project::class,
));
}
}
然后,您需要允许用户使用Twig和JavaScript动态地向项目添加活动,以便利用prototype
变量。
答案 2 :(得分:0)
我已经考虑了你所做的所有评论,并决定审查整个事情。
DecisionStatement.php:
documents = new ArrayCollection(); $ this-&gt; activitiesAffiliated = new ArrayCollection(); }
/**
* Get activitiesAffiliated
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getActivitiesAffiliated()
{
return $this->activitiesAffiliated;
}
我已经创建了一个新的FormType(DecisionStatementType.php),以获得我的表单集合:
use CoreBundle\Entity\DecisionStatement;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class DecisionStatementType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add(
'activitiesAffiliated',
CollectionType::class,
array(
'entry_type' => NewActivityType::class,
'allow_add' => true,
'allow_delete' => true
)
)
;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => DecisionStatement::class
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'corebundle_collection_decisionstatement';
}
}
这是“subForm”,newActivityType.php:
use CoreBundle\Entity\Activities;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class NewActivityType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add(
'aeAmount',
TextType::class,
array(
'label' => 'Montant de l\'AE',
'label_attr' => array(
'class' => 'aeAmount visuallyhidden'
),
'attr' => array(
'placeholder' => '80 000 €'
),
'required' => true
)
)
->add(
'amountSpent',
TextType::class,
array(
'label' => 'RDP : ',
'label_attr' => array(
'class' => 'amountSpent visuallyhidden'
),
'attr' => array(
'placeholder' => '35 000 €'
),
'required' => true,
)
)
->add(
'afName',
TextType::class,
array(
'required' => true,
'label' => 'AF : ',
'label_attr' => array(
'class' => 'afName visuallyhidden',
),
'attr' => array(
'placeholder' => 'AERT-496'
)
)
)
;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'CoreBundle\Entity\Activities'
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'corebundle_collection_activities';
}
}
在我看来的DOM中,我现在有了这个:
FormCollection Data-Prototype in DOM
那么,这有点清洁吗?