2013-06-18 2 views
2

내가 심포니에서 엔티티 필드에서 작동하는 dataTransformer를 얻기 위해 노력하고 있어요 2.symfony2 엔티티 양식 필드에 트랜스포머 적용 - 빈 배열?

상황 :

  • 폼 표시 사용자가 (체크 박스)을 선택할 수있는 항해는

  • 이는이다 다단계 항해 주문 절차의 첫 번째 단계 (이후 단계는 각 항해, 색상 등을 위해 사용 가능한 옵션을 표시)

이것은 내 양식 유형 클래스입니다.

위의 내용은 오류없이 작동하지만 변환 된 데이터는 표시하지 않습니다. 뷰는 다음과 같습니다

__ Race main 
__ Cruising main 

(체크 박스에 대한 __ 스탠드)

그러나, 내가 원하는 뷰는 다음과 같습니다

__ Race main ($1400) 
__ Cruising main ($800) 

내가 가진 변압기된다

use Symfony\Component\Form\DataTransformerInterface; 
use Symfony\Component\Form\Exception\TransformationFailedException; 
use Doctrine\Common\Persistence\ObjectManager; 
use Co\QuoteBundle\Entity\Sail; 
use Doctrine\Common\Collections\ArrayCollection; 

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

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

/** 
* Transforms a collection of sails to a collection of strings. 
* @param ISail|null $sail 
* @return string 
*/ 
public function transform($sailCollection) 
{ 
    if (null === $sailCollection) { 
     return null; 
    } 

    $labels = new ArrayCollection(); 

    foreach($sailCollection as $sail){ 
     $labels[] = $sail->getName().' ($'.$sail->getBuildPrice().')'; 
    } 

    return $labels; 
} 

//reverse transformer... not the issue (yet) because the forward transformer doesn't work 

} 

때 netbeans 디버거를 통해이를 실행하면 빈 배열이 변환기로 전달됩니다. 그러나 라인 58을 ->addViewTransformer($transformer));으로 변경하고 디버그하면 올바르게 변압기에 대한 배열 키로 돛 아이디가있는 두 개의 부울이 전달됩니다. 불행하게도 원래 문자열을 더 이상 포함하지 않기 때문에 ViewTransformer을 사용할 수 없습니다.

메인 돛을 포함해야하는 ArrayCollection이 빈 ArrayCollection으로 변환기에 전달되는 이유는 무엇입니까? 이 함수는 빈 $labels 컬렉션을 반환합니다.

내가 뭘 잘못하고 있는지 잘 모르겠다. 도움을 많이 주심 !! 감사합니다. .

답변

1

내가 시도한 것을 구현하는 방법을 찾지 못했습니다. 그러나 내가 사용한 해결 방법은 아래에 설명되어 있습니다. 폼 타입 클래스에 대한

, 나는 양식 이벤트 (symfony2 book)을 사용하고, 나는 부분과 같이, 컨트롤러에서 객체에 (돛이에 대응)을 boatId 저장된 :

$partsObject = new Parts($boat->getId()); 
$form = $this->createForm(new PartsTypeStep1(), $partsObject, array(
       'em' => $this->getDoctrine()->getManager())); 

양식 유형 클래스는 이제 다음과 같습니다 : 나는 또한 Mainsail 클래스의 displayString 속성을 추가하는 데 필요한

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\OptionsResolver\OptionsResolverInterface; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\Form\FormEvents; 
use Symfony\Component\Form\FormEvent; 
use Doctrine\ORM\EntityRepository; 

class PartsTypeStep1 extends AbstractType { 

public function setDefaultOptions(OptionsResolverInterface $resolver) 
{ 
    $resolver->setDefaults(array(
     'data_class' => 'Co\QuoteBundle\Entity\Parts',)); 

    $resolver->setRequired(array('em')); 
} 

public function buildForm(FormBuilderInterface $formBuilder, array $options) 
{    
    $factory = $formBuilder->getFormFactory(); 
    $em = $options['em']; 

    $formBuilder->addEventListener(
     FormEvents::PRE_SET_DATA, 
     function(FormEvent $event) use($factory, $em){ 
      $form = $event->getForm(); 
      $data = $event->getData(); 

      if (!$data || !$data->getDateTime()) { 
       return; 
      } 
      else { 
       $boatClass = $data->getBoatId(); 

       $formOptions = array(
          'class' => 'CoQuoteBundle:Mainsail', 
          'multiple' => true, 
          'expanded' => true, 
          'property' => 'displayString', 
          'label' => 'Mainsails', 
          'query_builder' => function(EntityRepository $er) use ($boatClass) { 
           return $er->createQueryBuilder('m') 
             ->where('m.boatType = :boatClass') 
             ->setParameter('boatClass', $boatClass); 
          }, 
         ); 
       $form->add($factory->createNamed('mainsailparts', 'entity', null, $formOptions)); 

       } 
     } 
    ); 

} 

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

(I 만 게터가 아닌 문자열에 대한 실제 변수를 추가).

public function getDisplayString(){ 
    return $this->name . ' - ' . $this->descr . ' ($' . $this->buildPrice . ')'; 
} 

나는이 해결 방법으로 우연히 유일한 문제는 쿼리가 빈 결과를 반환하는 경우 나뭇 가지가 자동으로 양식 레이블을 렌더링하는 것이기 때문에 일어나는 것이다 ('Mainsails') 여부 : 그래서 Mainsail 클래스는 이제이있다 렌더링 할 체크 박스가 없습니다.

  {% if form.mainsailparts|length > 0 %} 
       <div class="groupHeading">{{ form_label(form.mainsailparts) }}</div> 
       {% for child in form.mainsailparts %} 
        {# render each checkbox .... #} 

       {% endfor %} 
      {% else %} 
       {% do form.mainsailparts.setRendered %} 
      {% endif %} 

더 돛이 선택되지 않은 경우는이 경우에 권장되는 솔루션입니다 만약 내가 모르겠지만, 적어도 진행을 허용하지 (양식 유효성 검사와 함께 작동합니까, 내가 돈 :이 같은이 문제를 해결 있어요 더 엄격한 것을 필요로하지 않는다).

이 질문에 답할 수 없으므로 답변으로 표시하지 않을 것입니다 (항목을 트랜스 포머를 엔티티 필드에 적용하는 방법).하지만 같은 문제를 처리하는 모든 사람들에게 해결 방법입니다.