2014-09-03 94 views
1

我有一個PersonType窗體,然後我有LegalPersonTypeNaturalPersonType窗體,並且都從PersonType延伸,因爲它們具有該窗體上的公用字段(映射到實體級別)。例如,這是NaturalPersonType.php窗體繼承問題

use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolverInterface; 
use Tanane\FrontendBundle\DBAL\Types\CIType; 
use Tanane\FrontendBundle\Form\Type\PersonType; 

class NaturalPersonType extends PersonType { 

    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     parent::buildForm($builder, $options); 

     $builder 
       ->add('identification_type', 'choice', array(
        'label' => 'Número de Cédula', 
        'choices' => CIType::getChoices() 
       )) 
       ->add('ci', 'number', array(
        'required' => true, 
        'label' => false, 
        'attr' => array(
         'maxlength' => 8, 
        )) 
       ) 
       ->add('lives_in_ccs', 'checkbox', array(
        'label' => false, 
        'required' => false, 
        'value' => 1, 
     )); 
    } 

    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'Tanane\FrontendBundle\Entity\NaturalPerson' 
     )); 
    } 

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

} 

然後在SaveFormController/orderAction()我做這個代碼:

$order = new Orders(); 
$orderForm = $this->createForm(new OrdersType(array($type)), $order, array('action' => $this->generateUrl('save_order'))); 

但任何時候,我嘗試呈現我得到這個錯誤的形式:

Neither the property "nat" nor one of the methods "getNat()", "nat()", "isNat()", "hasNat()", "__get()" exist and have public access in class "Tanane\FrontendBundle\Entity\Orders".

關係處於實體級別,我如何解決該錯誤?

在此先感謝

1日可能的解決方案

在從用戶這裏我改變建議,在OrderType.php我的代碼的形式,以這樣的:

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolverInterface; 
use Tanane\FrontendBundle\DBAL\Types\SFType; 

class OrdersType extends AbstractType { 

    /** 
    * @var string 
    */ 
    protected $register_type; 

    public function __construct($register_type) 
    { 
     $this->register_type = $register_type; 
    } 

    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     // here goes $builder with default options remove for see less code 

     if ($this->register_type[0] == "natural") 
     { 
      $builder->add('nat', new NaturalPersonType(), array(
       'data_class' => 'Tanane\FrontendBundle\Entity\NaturalPerson' 
      )); 
     } 
     elseif ($this->register_type[0] == "legal") 
     { 
      $builder->add('leg', new LegalPersonType(), array(
       'data_class' => 'Tanane\FrontendBundle\Entity\LegalPerson' 
      )); 
     } 
    } 

    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'Tanane\FrontendBundle\Entity\Orders', 
      'render_fieldset' => FALSE, 
      'show_legend' => FALSE 
     )); 
    } 

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

} 

我已通過添加'mapped' => FALSE固定我在OrdersType中添加每個新的FormType,但我不知道這是否正確。另外,如果我在此處定義data_class,並且NaturalType將永遠不會直接訪問,只需要低谷OrdersType我應該從該表單中刪除默認選項,還是應該將它們留在那裏?我現在如何解決這個問題?我錯過了什麼?

回答

1

這不是直接回答你的問題,但在這之前發生,也許可以解決一些問題...

我不記得見過有可能擴展形式類似這樣的,而不是延長AbstractType,但正如文檔中所解釋的,如果您有不同類型的表單之間共享的公共字段,則應使用inherit_data提供的本機框架模塊化。

如果您需要更具體的某些特定方法(某些特定方法可在某個字段上執行),您可以使用AbstractTypeExtensioncreate a new field typeextend an existing one

編輯

我不知道究竟爲什麼要使用這種方法(即我從來沒有在我的項目中使用),但IMO PersonTypeNaturalPersonTypeLegalPersonType應該只是「FormType /的FieldType」與初始化inherit_data(而不是你的代碼中的實體),其中包含與其使用相關的字段,而OrdersType應該由填充它的人員類型所需的表單塊和設置在存儲數據的UNIQUE實體上的data_class組成由表單輸出。

+0

嗨,你能看看我的版嗎?在嘗試使用您的建議獲取代碼後,我仍然遇到一些問題 – ReynierPM 2014-09-03 12:03:00

+0

我更新了我的答案 – 2014-09-03 13:33:54

+0

嗯,我現在迷失了,您能否留下代碼示例? – ReynierPM 2014-09-03 19:32:22