2016-09-26 100 views
1

当我手工完成大部分代码时,我有一个由可变数量的div元素组成的表单,我通过提交后处理数组作为数组,但我不能在我的生活中弄清楚如何在Symfony中做类似的事情,我开始变得非常沮丧。这是我最初的实现模板类的一个对象(用我自己的简单的模板引擎):如何以Symfony的形式创建和渲染对象数组

<div class="img_transfer"> 
    <img class="toggle" src="{{src}}"> 
    <input class="title" type="text" name="title[{{i}}]" placeholder="Title"><br> 
    Upload to Sta.sh: 
    <input type="radio" name="stash[{{i}}]" value="0" checked="checked"> No 
    <input type="radio" name="stash[{{i}}]" value="1"> Yes<br> 
    Showcase: 
    <input type="radio" name="showcase[{{i}}]" value="0" checked="checked"> No 
    <input type="radio" name="showcase[{{i}}]" value="1"> Yes<br> 
    <input class="save" type="hidden" name="save[{{i}}]" value="0"> 
    <input type="hidden" name="old_path[{{i}}]" value="{{old_path}}"> 
</div> 

{{i}}是一个循环迭代的占位符,这是工作的罚款,但在这里是如何我一直努力做到在Symfony的:

$img_tmp = glob('img_tmp/*.*'); 
$data = array(); 
foreach ($img_tmp as $src) { 
    //$inter = end(); 
    $parts = explode('/', $src); 
    $file = end($parts); 
    //$name = explode($inter)[0]; 
    $name = explode('.', $file)[0]; 
    $data[$name] = new Art(); 
} 

$builder = $this->createFormBuilder($data); 
foreach ($data as $key => $value) { 
    //$builder->add($key, (new ArtType())->setSrc($key)); 
    $builder->add($key, ArtType::class, array('img_src' => $key)); 
} 

$form = $builder->getForm(); 

return $this->render('img_transfer.html.twig', array('form' => $form->createView())); 

这主要是基于SO对于如何有目标的一种形式的另一个建议,但因为是它不会让我的自定义选项,发送到形式来建,我认为这可能是我通过手工轻松实现的最终障碍。我完全欢迎大家提出建议,并希望采取更简单的方式来做到这一点,也很想知道我是否忽视了这样做的一种简单方法,或者如果这种方式与我感知的一样非常不直观它是。当我有时间时,我会编辑并重新构建这个问题是一个更好的问题。

编辑:格式和以下附加信息: 这个应用程序的特定部分是应该采取的“网络/ img_tmp”目录倾倒任意名称和扩展的图像,并将其移动到“网络/ img“目录,同时用PHP的uniqid()重命名它们并将它们输入到数据库中;我希望能为每个“/ img_tmp/.”生成一组分组字段,这样可以在将它们保存在数据库中之前为每个字段设置属性。我已经发现的关于如何一次提交多个对象的所有资源都不完整或者过于复杂。

回答

1

事实证明,我正在研究涉及不赞成使用的代码的解决方案,即我自定义类型的setDefaultOptions(OptionsResolverInterface $resolver)方法,该方法显然已在Symfony 3.0中删除。作为参考,下面是如何在一个形式通定制选项提交多个对象指向它们的完整代码:

控制器代码

public function someAction() 
{ 
    $vals = array('customVal1', 'customVal2', 'customVal3'); 
    foreach ($vals as $v) { 
     $data[$v] = new YourObject(); 
    } 

    $builder = $this->createFormBuilder($data); 
    //I put this here so I don't have to scroll all the way to the bottom to submit; 
    //this will render it at the top by default (at least on mine) 
    $builder->add('submit', SubmitType::class, array('label' => 'Submit')); 

    foreach ($vals as $v) { 
     $builder->add($v, YourObjectType::class, array(
      'custom_val' => $v 
     )); 
    } 

    $form = $builder->getForm(); 

    return $this->render('the_page.html.twig', array('form' => $form->createView())); 
} 

自定义表单模板

{% block yourobject_widget %} 
    <div> 
     <img src="{{ custom_val }}"> //This is set by the call to setAttribute() in YourObjectType 
     {% for child in form %} 
      {{ form_row(child) }} 
     {% endfor %} 
    </div> 
{% endblock %} 

应用/config/config.yml

twig: 
    debug:   "%kernel.debug%" 
    strict_variables: "%kernel.debug%" 
    form_themes: 
     - 'form/fields.html.twig' 

终于,YourObjectType

namespace AppBundle\Form\Type; 

use Symfony\Component\Form\AbstractType; 

use Symfony\Component\Form\Extension\Core\Type\TextType; 
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; 
use Symfony\Component\Form\Extension\Core\Type\CollectionType; 
use Symfony\Component\Form\Extension\Core\Type\HiddenType; 
use Symfony\Component\Form\Extension\Core\Type\SubmitType; 

use Symfony\Component\Form\FormView; 
use Symfony\Component\Form\FormInterface; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolver; 

class YourObjectType extends AbstractType 
{ 
    public function configureOptions(OptionsResolver $resolver) 
    { 
     parent::configureOptions($resolver); 

     $resolver->setDefaults(array(
      'data_class' => 'AppBundle\Entity\YourObject', 
      'custom_val' => '' //This is important. You have to set defaults for 
           //options for Symfony to allow you to pass them 
     )); 
    } 

    public function buildView(FormView $view, FormInterface $form, array $options) 
    { 
     $view->vars['custom_val'] = $options['custom_val']; 
    } 

    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->add('some_text_field', TextType::class) 
      ->add('some_choice_field', ChoiceType::class, array(
       'choices' => array('Yes' => true, 'No' => false), 
       'expanded' => true 
      )) 
      ->add('some_hidden_field', HiddenType::class, array('mapped' => false)) 
      ->setAttribute('custom_val', $options['custom_val']); 
    } 
}