【问题标题】:Form collection data pass [Symfony 4]表单收集数据传递 [Symfony 4]
【发布时间】:2019-10-26 22:02:06
【问题描述】:

我来找你解决脑残问题。

所以我有一个生成子表单的基本表单。我想将数组数据传递给子表单,但数组传递是数据失真的。

我也有一个关于我认为是链接的 CSRF 令牌的错误。 CSFR Error

控制器:

public function evaluatemocep($id,Request $request): Response
    {
        if ($this->getUser()) {
            $em = $this->getDoctrine()->getManager();
            $efficiency = new Efficiency();
            $problem = $em->getRepository('App:Problem')->find($id);
            $efficiency->setLinkProblem($problem);
            $form = $this->createForm(EfficiencyForm::class,$problem,['data'=>['id' => $id]]);
            $form->handleRequest($request);
            if ($form->isSubmitted() && $form->isValid()) {
                $em->persist($efficiency);
                $em->flush();
            }
                return $this->render('efficiency/efficiencyform.html.twig', [
                    'problem' => $problem,
                    'form' => $form->createView()]);
        }
        return new Response("You must be login");
    }

效率形式:

class EfficiencyForm extends AbstractType {

    /**
     * {@inheritDoc}
     */
    private $em;

    public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em;
    }

    public function buildForm(FormBuilderInterface $builder, array $options) {

        $problem = $this->em->getRepository(Problem::class)->find($options['data']['id']);
        $MOCrepo = $problem->getMOC();
        $EOrepo = $problem->getEO();
        $MOCA = array();
        $EOA = array();
        foreach ($EOrepo as $eo){
            array_push($EOA, $eo);
        }
        foreach ($MOCrepo as $moc){
            array_push($MOCA, $moc);
        }
                $builder->add('EffCollection', CollectionType::class, [
                    'entry_type' => EfficiencyMOCEOType::class,
                    'entry_options' => array('label' => false, 'EOA' => $EOA, 'MOCA' => $MOCA),
                    'allow_add' => true,
                    'prototype' => true,
                    'by_reference' => false,
                    'allow_delete' => true,
                    'mapped' => false,
                    'label' => 'Thinking about health'
                ]);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'allow_extra_fields' => true
        ]);
    }

    public function getBlockPrefix() {
        return 'RateCouple';
    }

}

效率MOCEO类型:

<?php

namespace App\Form;

use App\Entity\Efficiency;
use App\Entity\EO;
use App\Entity\MOC;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class EfficiencyMOCEOType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $EOA = $options['EOA'];
        $MOCA = $options['MOCA'];

        $builder
            ->add('EO', EntityType::class, [
                'class' => EO::class,
                'label' => 'Ethical objective',
                'choices' => $EOA,
                'choice_attr' => function ($choice){return ['title' => $choice->getDescription()];},
                'required' => true])
            ->add('MOC', EntityType::class,[
                'class' => MOC::class,
                'label' => 'Model Of Care',
                'choices' => $MOCA,
                'choice_attr' => function ($choice){return ['title' => $choice->getDescription()];},
                'required' => true])
            ->add('rateRiskCurrent', ChoiceType::class,[
                'label' => 'Evaluate the risks of the selected couple : ',
                'choices' => [
                    'High Risk' => 3,
                    'Medium Risk' => 2,
                    'Low Risk' => 1
                ],
                'required' => true
            ])
            ->add('rateBenefitCurrent', ChoiceType::class,[
                'label' => 'Evaluate the benefits of the selected couple : ',
                'choices' => [
                    'High Benefit' => 3,
                    'Medium Benefit' => 2,
                    'Low Benefit' => 1
                ],
                'required' => true
            ]);
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Efficiency::class,
            'MOCA' =>[],
            'EOA' => [],
            'allow_extra_fields' => true
        ]);
    }
}

树枝文件:

{% extends 'base.html.twig' %}

{% block title %}New efficiency evaluation{% endblock %}

{% block body %}
{{ form(form) }}

<div>
</div>
<fieldset>
    {{ form_start(form) }}

    <ul style="display: none" class="efficiencies" data-prototype="&lt;fieldset class=&quot;form-group&quot;&gt;&lt;div id=&quot;RateCouple_linkEfficiency___name__&quot;&gt;&lt;div class=&quot;form-group&quot;&gt;&lt;label class=&quot;required&quot; for=&quot;RateCouple_linkEfficiency___name___EO&quot;&gt;Ethical objective&lt;/label&gt;&lt;select id=&quot;RateCouple_linkEfficiency___name___EO&quot; name=&quot;RateCouple[linkEfficiency][__name__][EO]&quot; class=&quot;form-control&quot;&gt;&lt;option value=&quot;3&quot; title=&quot;DESC EO 1&quot;&gt;EO 1&lt;/option&gt;&lt;/select&gt;&lt;/div&gt;&lt;div class=&quot;form-group&quot;&gt;&lt;label class=&quot;required&quot; for=&quot;RateCouple_linkEfficiency___name___MOC&quot;&gt;Model Of Care&lt;/label&gt;&lt;select id=&quot;RateCouple_linkEfficiency___name___MOC&quot; name=&quot;RateCouple[linkEfficiency][__name__][MOC]&quot; class=&quot;form-control&quot;&gt;&lt;option value=&quot;3&quot; title=&quot;DESC MOC 1&quot;&gt;MOC 1&lt;/option&gt;&lt;/select&gt;&lt;/div&gt;&lt;div class=&quot;form-group&quot;&gt;&lt;label class=&quot;required&quot; for=&quot;RateCouple_linkEfficiency___name___rateRiskCurrent&quot;&gt;Evaluate the risks of the selected couple : &lt;/label&gt;&lt;select id=&quot;RateCouple_linkEfficiency___name___rateRiskCurrent&quot; name=&quot;RateCouple[linkEfficiency][__name__][rateRiskCurrent]&quot; class=&quot;form-control&quot;&gt;&lt;option value=&quot;3&quot;&gt;High Risk&lt;/option&gt;&lt;option value=&quot;2&quot;&gt;Medium Risk&lt;/option&gt;&lt;option value=&quot;1&quot;&gt;Low Risk&lt;/option&gt;&lt;/select&gt;&lt;/div&gt;&lt;div class=&quot;form-group&quot;&gt;&lt;label class=&quot;required&quot; for=&quot;RateCouple_linkEfficiency___name___rateBenefitCurrent&quot;&gt;Evaluate the benefits of the selected couple : &lt;/label&gt;&lt;select id=&quot;RateCouple_linkEfficiency___name___rateBenefitCurrent&quot; name=&quot;RateCouple[linkEfficiency][__name__][rateBenefitCurrent]&quot; class=&quot;form-control&quot;&gt;&lt;option value=&quot;3&quot;&gt;High Benefit&lt;/option&gt;&lt;option value=&quot;2&quot;&gt;Medium Benefit&lt;/option&gt;&lt;option value=&quot;1&quot;&gt;Low Benefit&lt;/option&gt;&lt;/select&gt;&lt;/div&gt;&lt;/div&gt;&lt;/fieldset&gt;">
    </ul>
        <ul class="efficiencies">
            {% for efficiency in form.EffCollection %}
                <li>
                    {{ form_row(efficiency.EO) }}
                    </br>
                    {{ form_row(efficiency.MOC) }}
                    </br>
                    {{ form_row(efficiency.rateRiskCurrent) }}
                    </br>
                    {{ form_row(efficiency.rateBenefitCurrent) }}

                </li>
            {% endfor %}
        </ul>
    <input type="submit" value="Submit" class="btn btn-primary btn-block" />

    {{ form_end(form) }}

    <script>

        var efficiency_template = document.getElementById("efficiencies");

        function addNewEfficiency(){
            var dup_efficiency_template = efficiency_template.cloneNode(true);
            document.getElementById("list_of_efficiency").append(dup_efficiency_template);
        }

    </script>

    {% endblock %}
    {% block javascripts %}
        <script>

            var $collectionHolderEfficiency;

            var $addEfficiencyButton = $('<button type="button" class="btn btn-secondary btn-success">Add an efficiency row</button>');

            var $newEfficiencyLinkLi = $('<li></li>').append($addEfficiencyButton);


            jQuery(document).ready(function() {
                $collectionHolderEfficiency = $('ul.efficiencies');

                $collectionHolderEfficiency.find('li').each(function () {
                    addEfficiencyFormDeleteLink($(this));
                });
                $collectionHolderEfficiency.append($newEfficiencyLinkLi);
                $collectionHolderEfficiency.data('index', $collectionHolderEfficiency.find(':input').length);
                $addEfficiencyButton.on('click', function (e) {
                    addEfficiencyForm($collectionHolderEfficiency, $newEfficiencyLinkLi);
                });
            });



            function addEfficiencyForm($collectionHolderEfficiency, $newEfficiencyLinkLi) {
                var prototype = $collectionHolderEfficiency.data('prototype');
                var index = $collectionHolderEfficiency.data('index');
                var newForm = prototype;
                newForm = newForm.replace(/__name__/g, index);
                $collectionHolderEfficiency.data('index', index + 1);
                var $newFormLi = $('<li></li>').append(newForm);
                addEfficiencyFormDeleteLink($newFormLi);
                $newEfficiencyLinkLi.before($newFormLi);
            }


            function addEfficiencyFormDeleteLink($efficiencyFormLi) {
                var $removeFormButton = $('<button type="button" class="btn btn-secondary btn-danger">Delete this efficiency row</button>');
                $efficiencyFormLi.append($removeFormButton);
                $removeFormButton.on('click', function(e) {
                    $efficiencyFormLi.remove();
                });
            }

        </script>
</fieldset>
    {% endblock %}

任何帮助将不胜感激!

【问题讨论】:

  • 您好,如果您能更详细地描述实际问题是什么,这将很有帮助,因为“我想将数组数据传递给子表单,但数组传递是数据失真。”不是特别清楚。由于您的表单已经将问题实体传递给它,因此您不应将其 id 作为选项传递,而应使用表单事件,特别是 PRE_SET_DATA 表单事件。一般来说,数据访问应该是自动的,而不是通过选项来完成,如果可以的话。表单组件实际上非常聪明,您应该发挥它的优势。
  • 问题是我将数据($EOA 和 $MOCA)传递给第二种形式,但我在第二种形式中的数据不是我在第一种形式中获得的数据。我会尝试克服 id argu 看看是否有区别!
  • 解决了 CSRF 问题,但我的子表单上仍然没有得到正确的数据
  • 好吧,我可以告诉你,就可见范围而言,eoa/moca 数组应该是正确的。您如何验证/检查它们不是?
  • 我直接从数据库中检查 $EOA 和 $MOCA 是基于与问题实体多对多相关的实体的数组,例如问题 id 4 得到 2 EO 和 2 MOC,但形式为 i只得到一个带有错误标签的标签(我实际上得到了问题 1 的 EO 和 MOC ..)

标签: php symfony4 formcollection csrf-token


【解决方案1】:

所以我发现原型链接不起作用我解决了错误的数据传输但我现在有不显示的表格,我找不到我的错误

这是我的树枝:


{% block title %}New efficiency evaluation{% endblock %}

{% block body %}
{{ form(form) }}
<fieldset>
    {{ form_start(form) }}

    <ul style="display: none" id="efficiencies-proto" class="efficiencies" data-prototype="{{ form_widget(form.efficiencies.vars.prototype)|e('html_attr') }}">
    </ul>
        <ul class="efficiencies">
            {% for efficiency in form.efficiencies %}
                <li>
                    {{ form_row(efficiency.EO) }}
                    </br>
                    {{ form_row(efficiency.MOC) }}
                    </br>
                    {{ form_row(efficiency.rateRiskCurrent) }}
                    </br>
                    {{ form_row(efficiency.rateBenefitCurrent) }}

                </li>
            {% endfor %}
        </ul>
    {{ form_end(form) }}
    {% endblock %}
    {% block javascripts %}
        <script>

            var $collectionHolderEfficiency;

            var $addEfficiencyButton = $('<button type="button" class="btn btn-secondary btn-success">Add an efficiency row</button>');

            var $newEfficiencyLinkLi = $('<li></li>').append($addEfficiencyButton);


            jQuery(document).ready(function() {
                $collectionHolderEfficiency = $('ul.efficiencies');

                $collectionHolderEfficiency.find('li').each(function () {
                    addEfficiencyFormDeleteLink($(this));
                });
                $collectionHolderEfficiency.append($newEfficiencyLinkLi);
                $collectionHolderEfficiency.data('index', $collectionHolderEfficiency.find(':input').length);
                $addEfficiencyButton.on('click', function (e) {
                    addEfficiencyForm($collectionHolderEfficiency, $newEfficiencyLinkLi);
                });
            });



            function addEfficiencyForm($collectionHolderEfficiency, $newEfficiencyLinkLi) {
                var prototype = $collectionHolderEfficiency.data('prototype');
                var index = $collectionHolderEfficiency.data('index');
                var newForm = prototype;
                newForm = newForm.replace(/__name__/g, index);
                $collectionHolderEfficiency.data('index', index + 1);
                var $newFormLi = $('<li></li>').append(newForm);
                addEfficiencyFormDeleteLink($newFormLi);
                $newEfficiencyLinkLi.before($newFormLi);
            }


            function addEfficiencyFormDeleteLink($efficiencyFormLi) {
                var $removeFormButton = $('<button type="button" class="btn btn-secondary btn-danger">Delete this efficiency row</button>');
                $efficiencyFormLi.append($removeFormButton);
                $removeFormButton.on('click', function(e) {
                    $efficiencyFormLi.remove();
                });
            }

        </script>
</fieldset>
    {% endblock %}

效率形式:

<?php


namespace App\Form;
use App\Entity\Efficiency;
use App\Entity\EO;
use App\Entity\MOC;
use App\Entity\Problem;
use Doctrine\ORM\EntityRepository;
use phpDocumentor\Reflection\Types\Null_;
use PhpParser\Node\Expr\Array_;
use Symfony\Component\Form\AbstractType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;


class EfficiencyForm extends AbstractType {

    /**
     * {@inheritDoc}
     */
    private $em;

    public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em;
    }

    public function buildForm(FormBuilderInterface $builder, array $options) {

        $problem = $this->em->getRepository(Problem::class)->find($options['data']['id']);
        $MOCrepo = $problem->getMOC();
        $EOrepo = $problem->getEO();
        $MOCA = array();
        $EOA = array();
        $interom = 0;
        foreach ($EOrepo as $eo){
            array_push($EOA, $eo);
            $interom ++;
        }
        foreach ($MOCrepo as $moc){
            array_push($MOCA, $moc);
        }
                $builder
                    ->add('efficiencies', CollectionType::class, [
                    'entry_type' => EfficiencyMOCEOType::class,
                    'entry_options' => array('label' => false, 'EOA' => $EOA, 'MOCA' => $MOCA),
                    'allow_add' => true,
                    'prototype' => true,
                    'by_reference' => false,
                    'allow_delete' => true,
                    'mapped' => false,
                    'label' => 'Thinking about health'
                ])
                    ->add("submit", SubmitType::class, [
                    "label" => $options["submit_button_label"],
                    "attr" => [
                        "class" => "btn btn-primary btn-bloc pull-right"
                    ]
                ])
                ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'allow_extra_fields' => true,
            "submit_button_label" => "Submit evaluation"
        ]);
    }

    public function getBlockPrefix() {
        return 'efficiencyOne';
    }

}

效率MOCEO类型:

<?php

namespace App\Form;

use App\Entity\Efficiency;
use App\Entity\EO;
use App\Entity\MOC;
use phpDocumentor\Reflection\Type;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class EfficiencyMOCEOType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $EOA = $options['EOA'];
        $MOCA = $options['MOCA'];

        foreach ($MOCA as $moc) {
            var_dump($moc->getName());
        }
        foreach ($EOA as $eo) {
            var_dump($eo->getName());
        }
        var_dump(gettype($EOA));
        var_dump(gettype($MOCA));
        $builder
            ->add('EO', EntityType::class, [
                'class' => EO::class,
                'label' => 'Ethical objective',
                'choices' => $EOA,
                'choice_attr' => function ($choice){return ['title' => $choice->getDescription()];},
                'required' => true])
            ->add('MOC', EntityType::class,[
                'class' => MOC::class,
                'label' => 'Model Of Care',
                'choices' => $MOCA,
                'choice_attr' => function ($choice){return ['title' => $choice->getDescription()];},
                'required' => true])
            ->add('rateRiskCurrent', ChoiceType::class,[
                'label' => 'Evaluate the risks of the selected couple : ',
                'choices' => [
                    'High Risk' => 3,
                    'Medium Risk' => 2,
                    'Low Risk' => 1
                ],
                'required' => true
            ])
            ->add('rateBenefitCurrent', ChoiceType::class,[
                'label' => 'Evaluate the benefits of the selected couple : ',
                'choices' => [
                    'High Benefit' => 3,
                    'Medium Benefit' => 2,
                    'Low Benefit' => 1
                ],
                'required' => true
            ]);
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'MOCA' =>[],
            'EOA' => [],
            'allow_extra_fields' => true
        ]);
    }
}

【讨论】:

    猜你喜欢
    • 2019-05-23
    • 1970-01-01
    • 2020-01-09
    • 1970-01-01
    • 1970-01-01
    • 2019-05-25
    • 1970-01-01
    • 1970-01-01
    • 2020-02-06
    相关资源
    最近更新 更多