2014-02-17 27 views
3

我試圖創建一個自定義選擇列表字段。 除了編輯部分的預選值之外,幾乎所有的東西都顯得有效。我知道這是一個骯髒的方式來操作,但我沒有找到一個更好的解決方案(保持簡單的事情)。我想創建一個混合列表字段與多個對象類型(後端是mongodb)。 該過程的工作,我有在後端的混合對象和我可以選擇哪一個在編輯形式,但形式沒有示出預選(與來自蒙戈提取的值)的Symfony2 DataTransformer供選擇現場

<?php 
namespace www\DefaultBundle\Form\Type; 

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use www\DefaultBundle\Form\DataTransformer\AccessorioTransformer; 
use Doctrine\Common\Persistence\ObjectManager; 
use Symfony\Component\OptionsResolver\OptionsResolverInterface; 

class AccessorioType extends AbstractType 
{ 
    /** 
    * @var ObjectManager 
    */ 
    private $om; 

    /** 
    * @param ObjectManager $om 
    */ 
    public function __construct(ObjectManager $om) 
    { 
     $this->om = $om; 
    } 


    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $transformer = new AccessorioTransformer($this->om); 
     $builder->addModelTransformer($transformer); 
    } 


    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $choices = array(); 
     $data = array(); 
     $documents = array(
      'Document1', 
      'Document2', 
      'Document3', 
      ); 

     foreach ($documents as $document) 
     { 
      $objects = $this->om->getRepository('wwwDefaultBundle:' . $document)->findAll(); 
      foreach ($objects as $object) 
      { 
       if (@!$object->getId()) print_r($object); 
       $key = sprintf("%s_%s", $object->getId(), basename(str_replace('\\', '/', get_class($object)))); 
       $value = sprintf("%s (%s)", $object, basename(str_replace('\\', '/', get_class($object)))); 
       $choices[$key] = $value; 
      } 
     } 

     $resolver->setDefaults(array(
      'choices' => $choices, 
      'expanded' => false, 
      'multiple' => true, 
     )); 

    } 


    public function getParent() 
    { 
     return 'choice'; 
    } 

    public function getName() 
    { 
     return 'accessorio'; 
    } 
} 

的datatransformer:

<?php 
namespace www\DefaultBundle\Form\DataTransformer; 

use Symfony\Component\Form\DataTransformerInterface; 
use Symfony\Component\Form\Extension\Core\ObjectChoiceList; 
use Symfony\Component\Form\Exception\TransformationFailedException; 
use Doctrine\Common\Persistence\ObjectManager; 
use Acme\TaskBundle\Entity\Issue; 

class AccessorioTransformer implements DataTransformerInterface 
{ 
    /** 
    * @var ObjectManager 
    */ 
    private $om; 

    /** 
    * @param ObjectManager $om 
    */ 
    public function __construct(ObjectManager $om) 
    { 
     $this->om = $om; 
    } 


    public function transform($values) 
    { 
     return array(); 
     // i tried everything here but none working 

    } 


    public function reverseTransform($values) 
    { 
     if (!$values) return null; 

     $array = array(); 

     foreach ($values as $value) 
     { 
      list($id, $type) = explode("_", $value); 
      $array[] = $this->om->getRepository('wwwDefaultBundle:' . $type)->find($id); 
     } 

     return $array; 
    } 
} 

表單生成器:

<?php 

namespace www\DefaultBundle\Form; 

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolverInterface; 

class ValvolaType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 

      // [snip] 

      ->add('ref', 
       'accessorio', 
       array(
        'label_attr' => array('class' => 'control-label col-sm-2'), 
        'attr'  => array('class' => 'form-control '), 
       )) 
     ; 
    } 

    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'www\DefaultBundle\Document\Valvola', 
      'attr'  => array('class' => 'press form-horizontal'), 
     )); 
    } 

    public function getName() 
    { 
     return 'www_defaultbundle_valvolatype'; 
    } 
} 

是否有人遇到同樣的問題?如何「選擇」領域應該改變?如何在同一領域管理混合對象? 有人可以啓發我嗎?

Regards

+0

感嘆,我有同樣的問題。嘗試使用更多信息編輯您的問題,或者嘗試使其更清楚。這會「碰撞」你的問題,而不是你必須刪除並重新制作你的問題。這是你唯一的選擇,因爲你沒有聲望放棄賞金,但... – Tek

回答

4

我終於找到了解決方案。罪魁禍首是datatransformer(和礦,當然:-)的) 以這種方式,形式示出了預選值:

<?php 
namespace www\DefaultBundle\Form\DataTransformer; 

use Symfony\Component\Form\DataTransformerInterface; 
use Symfony\Component\Form\Extension\Core\ObjectChoiceList; 
use Symfony\Component\Form\Exception\TransformationFailedException; 
use Doctrine\Common\Persistence\ObjectManager; 
use Acme\TaskBundle\Entity\Issue; 

class AccessorioTransformer implements DataTransformerInterface 
{ 
    /** 
    * @var ObjectManager 
    */ 
    private $om; 

    /** 
    * @param ObjectManager $om 
    */ 
    public function __construct(ObjectManager $om) 
    { 
     $this->om = $om; 
    } 


    public function transform($values) 
    { 
     if ($values === null) return array(); 

     $choices = array(); 
     foreach ($values as $object) 
     { 
      $choices[] = sprintf("%s_%s", $object->getId(), basename(str_replace('\\', '/', get_class($object)))); 
     } 

     return $choices; 
    } 


    public function reverseTransform($values) 
    { 
     if (!$values) return array(); 

     $array = array(); 

     foreach ($values as $value) 
     { 
      list($id, $type) = explode("_", $value); 
      $array[] = $this->om->getRepository('wwwDefaultBundle:' . $type)->find($id); 
     } 

     return $array; 
    } 
} 
0

在大多數情況下使用由ChoiceType變換函數返回的數組應該只包含ID的。例如:

public function transform($objectsArray) 
{ 
    $choices = array(); 

    foreach ($objectsArray as $object) 
    { 
     $choices[] = $object->getId(); 
    } 

    return $choices; 
} 

雖然它可能不是原始帖子的答案,但我非常確定googlers會到達此處並查找此提示。