【问题标题】:Symfony2 collection always emptySymfony2 集合总是空的
【发布时间】:2015-10-26 23:07:27
【问题描述】:

我有一个无法解决的问题。我有 2 个实体:

<?php
namespace ...\Entity;

// ...

/**
 * Pregunta
 *
 * @ORM\Table(name="pregunta", indexes={@ORM\Index(name="fk_respuesta_tipo_respuesta1_idx", columns={"tipo_respuesta_id"}))})
 * @ORM\Entity 
 */
class Pregunta {

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var \Doctrine\Common\Collections\Collection
     *
     * @ORM\ManyToMany(targetEntity="...\Entity\Respuesta", mappedBy="pregunta")
     */
    private $respuesta;


    public function __construct() {
        $this->tipoPrueba = new \Doctrine\Common\Collections\ArrayCollection();
        $this->respuesta = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Add respuesta
     *
     * @param ...\Entity\Respuesta $respuesta
     * @return Pregunta
     */
    public function addRespuesta(...\Entity\Respuesta $respuesta) {
        $this->respuesta[] = $respuesta;

        return $this;
    }

    /**
     * Remove respuesta
     *
     * @param ...\Entity\Respuesta $respuesta
     */
    public function removeRespuesta(...\Entity\Respuesta $respuesta) {
        $this->respuesta->removeElement($respuesta);
    }

    /**
     * Get respuesta
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getRespuesta() {
        return $this->respuesta;
    }

    function setRespuesta(\Doctrine\Common\Collections\Collection $respuesta) {
        $this->respuesta = $respuesta;
    }
}

然后我有Respuesta 实体:

<?php
class Respuesta {

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="texto_respuesta", type="text", nullable=false)
     */
    private $textoRespuesta;

    // ...

我有一个PreguntaType,它有它的字段和RespuestaType 的集合:

/**
 * @param FormBuilderInterface $builder
 * @param array $options
 */
public function buildForm(FormBuilderInterface $builder, array $options) {
    $builder
            ->add('titulo', 'textarea', array("label" => "Enunciado: ", "required" => true, "attr" => array('class' => 'form-control')))
            ->add('numeroPagina', 'integer', array("label" => "Página: ", "required" => true, "attr" => array('class' => 'form-control')))
            ->add('areaConocimiento', 'entity', array('class' => 'UciBaseDatosBundle:AreaConocimiento', 'required' => false, 'attr' => array('style' => 'width: 100%')))
            ->add('trianguloTalento', 'entity', array('class' => 'UciBaseDatosBundle:TrianguloTalento', 'required' => false, 'attr' => array('style' => 'width: 100%')))
            ->add('capitulo', 'entity', array('class' => 'UciBaseDatosBundle:Capitulo', 'required' => false, 'attr' => array('style' => 'width: 100%')))
            ->add('grupoProcesos', 'entity', array('class' => 'UciBaseDatosBundle:GrupoProcesos', 'required' => false, 'attr' => array('style' => 'width: 100%')))
            ->add('tipoPrueba', 'entity', array('class' => 'UciBaseDatosBundle:TipoPrueba', 'expanded' => true, 'multiple' => true, 'required' => false, 'attr' => array('style' => 'width: 100%')))
            ->add('libro', 'entity', array('class' => 'UciBaseDatosBundle:Libro', 'required' => false, 'attr' => array('style' => 'width: 100%')))
            ->add('respuesta', 'collection', array(
                'type' => new RespuestaType(),
                'prototype' => true,
                'allow_add' => true,
                'by_reference' => false,
                'allow_delete' => true,
                'label' => ' '
    ));
}

/**
 * @param OptionsResolverInterface $resolver
 */
public function setDefaultOptions(OptionsResolverInterface $resolver) {
    $resolver->setDefaults(array(
        'data_class' => 'Uci\Bundle\BaseDatosBundle\Entity\Pregunta'
    ));
}

但是,当我调试表单提交时,如果我将集合设置为 'required' =&gt; true,则会引发此错误 An invalid form control with name='...[respuesta][Respuesta0][RespuestaField]' is not focusable。另一方面,如果我将其设置为'required' =&gt; false,我的收藏字段始终为空。

这是我的 TWIG 文件:

<form action="{{ path('uci_administrador_registrarPregunta', { 'idTipoRespuesta': tipoRespuesta.id }) }}" name="formulario" method="POST" enctype="multipart/form-data">             
    <h3 class="thin text-center">Registrar una nueva pregunta {{ tipoRespuesta.nombre }}</h3>
    <p class="text-center text-muted">{{ tipoRespuesta.explicacion }}</p>
    <hr>

    {% if error %}
        <div style="color:red">{{ error }}</div>
    {% endif %}

    <div class="row top-margin">
        <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8">
            {{ form_row(form.titulo) }}
        </div>
    </div>
    <div class="row top-margin">
        <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8">
            {{ form_row(form.numeroPagina) }}
        </div>
    </div>
    <div class="row top-margin">
        <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8">
            {{ form_row(form.areaConocimiento) }}
        </div>
    </div>
    <div class="row top-margin">
        <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8">
            {{ form_row(form.capitulo) }}
        </div>
    </div>
    <div class="row top-margin">
        <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8">
            {{ form_row(form.grupoProcesos) }}
        </div>
    </div>
    <div class="row top-margin">
        <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8">
            {{ form_row(form.trianguloTalento) }}
        </div>
    </div>
    <div class="row top-margin">
        <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8">
            {{ form_row(form.tipoPrueba) }}
        </div>
    </div>
    <div class="row top-margin">
        <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8">
            {{ form_row(form.libro) }}
        </div>
    </div>
    <br>
    <hr>
    <h3>Respuestas</h3><br>
    <div class="respuestas" data-prototype="{{ form_widget(form.respuesta.vars.prototype)|e }}">
        {# iterate over each existing tag and render its only field: name #}
        {% for respuesta in form.respuesta %}
            <div class="row top-margin">
                <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8">
                    {{ form_row(respuesta.correcta) }}
                </div>
            </div>
        {% endfor %}
    </div>
    <br><br>
    <div class="row">
        <div class="col-lg-8">                     
        </div>
        <div class="col-lg-4 text-right">
            <button class="btn btn-action" type="submit">Registrar</button>
        </div>
    </div>
    {{ form_rest(form) }}
</form>

我使用一些 javascript 来添加我的收藏表单:

var $collectionHolder;
// setup an "add a tag" link
var $addTagLink = $('<a href="#" class="add_tag_link">Añadir respuesta</a>');
var $newLinkLi = $('<div></div>').append($addTagLink);
function addTagForm($collectionHolder, $newLinkLi) {
    // Get the data-prototype explained earlier
    var prototype = $collectionHolder.data('prototype');
    // get the new index
    var index = $collectionHolder.data('index');
    // Replace '__name__' in the prototype's HTML to
    // instead be a number based on how many items we have
    var newForm = prototype.replace(/__name__/g, 'Respuesta' + index);
    // increase the index with one for the next item
    $collectionHolder.data('index', $collectionHolder.find(':input').length);
    // Display the form in the page in an li, before the "Add a tag" link li
    var $newFormLi = $('<div style="background-color:#F6F6F6; border-radius:10px;padding: 25px;border: 5px solid #003c70;margin: 5px;"></div><br>').append(newForm);
    $newLinkLi.before($newFormLi);
}
document.ready = function () {
    // Get the ul that holds the collection of tags
    $collectionHolder = $('div.respuestas');
    // add the "add a tag" anchor and li to the tags ul
    $collectionHolder.append($newLinkLi);
    // count the current form inputs we have (e.g. 2), use that as the new
    // index when inserting a new item (e.g. 2)
    $collectionHolder.data('index', $collectionHolder.find(':input').length);
    $addTagLink.on('click', function (e) {
        // prevent the link from creating a "#" on the URL
        e.preventDefault();
        // add a new tag form (see next code block)
        addTagForm($collectionHolder, $newLinkLi);
    });

    // ...
}

非常感谢任何帮助。

谢谢。

【问题讨论】:

  • 如何在前端显示表单?请在您的问题中添加模板中的一些代码。

标签: forms symfony collections


【解决方案1】:

我的问题出在我的 javascript 中。我不知道为什么我以前的代码不起作用,但我改变了它并且它起作用了。我的javascript如下:

var collectionHolder = $('#respuestas');
var prototype = collectionHolder.attr('data-prototype');
var form = prototype.replace(/__name__/g, collectionHolder.children().length); //importante
var removeFormA = $('<a href="#" onclick="addTagFormDeleteLink(event, this);">Borrar</a>');
var newLi = $('<li></li>');
newLi.append(form);
newLi.append(removeFormA);
collectionHolder.append(newLi);

这是我的 TWIG 文件的一部分:

<ul id="respuestas" data-prototype="{{ form_widget(form.respuesta.vars.prototype)|e }}">
{% for respuesta in form.respuesta %}
      <li> {{ form_row(respuesta) }}</li>
{% endfor %}
</ul>

我希望它可以帮助别人。

问候。

【讨论】:

    【解决方案2】:

    您是否要隐藏表单中的某些字段?看起来某些字段是必需的,但实际上并未显示在页面中,这会阻止浏览器验证表单。参考那个答案:https://stackoverflow.com/a/28340579/4114297

    我想知道为什么你只在循环中渲染respuesta.correcta。您可能想要渲染 while respuesta 项目:

    <div class="respuestas" data-prototype="{{ form_widget(form.respuesta.vars.prototype)|e }}">
        {# iterate over each existing tag and render its only field: name #}
        {% for respuesta in form.respuesta %}
            <div class="row top-margin">
                <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8">
                    {{ form_row(respuesta) }} {# <- Here #}
                </div>
            </div>
        {% endfor %}
    </div>
    

    如果您需要隐藏和/或预填充某些字段,您可以这样做RespuestaType

    【讨论】:

    • 感谢您的帮助@paulvg。我没有隐藏字段。当我尝试提交表单时,它说:“名称='uci_bundle_basedatosbundle_pregunta[respuesta][Respuesta0][textoRetroalimentacion]'的无效表单控件不可聚焦。”,与其他 Respuesta 字段相同。我改变了循环,但它抛出了同样的错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-18
    • 2019-11-11
    • 1970-01-01
    • 1970-01-01
    • 2013-10-28
    相关资源
    最近更新 更多