2014-02-17 5 views
3

사용자 정의 선택 목록 필드를 만들려고합니다. 그리고 편집 부분의 미리 선택된 값을 제외하고 거의 모든 것이 작동하는 것처럼 보입니다.Symfony2 선택 필드 용 DataTransformer

기본적으로 다중 객체 유형 (백엔드는 mongodb 임)이 혼합 된 목록 필드를 만들고 있습니다. 더러운 방법으로 작동하지만 더 나은 솔루션을 찾지 못했습니다. 프로세스는 작동 나는 백엔드 혼합 개체가 나는 편집 형태의 어느 하나를 선택할 수 있지만, 형태가 미리 선택된 표시되지 않는

<?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'; 
    } 
} 

사람이 같은 문제에 직면 했습니까? 어떻게 "선택"필드가 변형되어야 하는가? 동일한 필드에서 혼합 된 객체를 관리하는 방법은 무엇입니까? 누군가 나를 가르 칠 수 있습니까?

감사합니다.

+0

한숨, 나는 동일한 문제가 있습니다. 자세한 정보로 질문을 편집하거나 더 명확하게 해보십시오. 이렇게하면 질문을 삭제하고 다시 작성해야하는 것이 아니라 질문에 "충돌"합니다. 현상금에 대해 아직 알려주지 않은 평판이 있기 때문에 유일한 선택입니다 ... – Tek

답변

4

마지막으로 해결책을 찾았습니다. ID 용 만 포함해야 ChoiceType에게 변환 함수에 의해 리턴 된 배열을 사용하여 대부분의 경우

<?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

: 범인은 형태가 미리 선택된 값을 나타내고 이러한 방식으로 datatransformer (와 광산, 코스 :-)의) 이었다 . 예 :

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

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

    return $choices; 
} 

원래 게시물에 대한 답변이 아닐지 모르지만 나는 Google 직원이 여기에 와서이 힌트를 찾습니다.