2016-07-30 32 views
1

Ich habe Probleme mit ZF2 Annotationsformularen. Werte, die "Objekt zusammengesetzt" haben, setzen nicht den Standardwert. Ich habe meinen Code angehängt.zf2 Formen legen Wert nicht in zusammengesetztem Objekt fest

Warum legt das Formular in MetaContent-Objektzeilen keinen Wert fest? Was mache ich falsch? In Controller, als ich schrieb "echo $ category-> getMetaContent() -> getMetaDescription();" es zeigte richtigen Wert

<?php 
 

 
namespace Application\Entity; 
 

 
use Doctrine\ORM\Mapping as ORM; 
 
use Zend\Form\Annotation; 
 

 
/** 
 
* BlogCategory 
 
* 
 
* @ORM\Table(name="blog_category", indexes={@ORM\Index(name="category_parent_idx", columns={"parent_id"})}) 
 
* @ORM\Entity 
 
* 
 
* @Annotation\Hydrator("Zend\Stdlib\Hydrator\ObjectProperty") 
 
* @Annotation\Name("Category") 
 
*/ 
 
class BlogCategory 
 
{ 
 
    /** 
 
    * @var integer 
 
    * 
 
    * @ORM\Column(name="id", type="integer", nullable=false) 
 
    * @ORM\Id 
 
    * @ORM\GeneratedValue(strategy="IDENTITY") 
 
    * 
 
    * @Annotation\Exclude() 
 
    */ 
 
    private $id; 
 
    
 
    * @Annotation\Filter({"name":"StripTags"}) 
 
    * @Annotation\Required({"required":"true"}) 
 
    * @Annotation\Attributes({"class":"gui-input"}) 
 
    */ 
 
    private $name; 
 
    
 
    
 
    /** 
 
    * @var \Application\Entity\MetaContent 
 
    * 
 
    * @ORM\ManyToOne(targetEntity="Application\Entity\MetaContent", cascade={"persist"}) 
 
    * @ORM\JoinColumns({ 
 
    * @ORM\JoinColumn(name="meta_content_id", referencedColumnName="id") 
 
    * }) 
 
    * 
 
    * 
 
    * @Annotation\ComposedObject("Application\Entity\MetaContent") 
 
    * @Annotation\Options({"label":"Meta content:", "label_options":{"class":"control-label"}}) 
 
    */ 
 
    private $metaContent;

<?php 
 

 
namespace Application\Entity; 
 

 
use Doctrine\ORM\Mapping as ORM; 
 
use Zend\Form\Annotation; 
 

 
/** 
 
* MetaContent 
 
* 
 
* @ORM\Table(name="meta_content") 
 
* @ORM\Entity 
 
* 
 
* @Annotation\Name("MetaContent") 
 
*/ 
 
class MetaContent 
 
{ 
 
    /** 
 
    * @var integer 
 
    * 
 
    * @ORM\Column(name="id", type="integer", nullable=false) 
 
    * @ORM\Id 
 
    * @ORM\GeneratedValue(strategy="IDENTITY") 
 
    * 
 
    * @Annotation\Attributes({"type":"hidden"}) 
 
    * @Annotation\AllowEmpty(true) 
 
    */ 
 
    private $id; 
 

 
    /** 
 
    * @var string 
 
    * 
 
    * @ORM\Column(name="meta_description", type="string", length=255, nullable=true) 
 
    * 
 
    * @Annotation\Type("Zend\Form\Element\Text") 
 
    * @Annotation\Required({"required":"true"}) 
 
    * @Annotation\Options({"label":"Meta description:"}) 
 
    * @Annotation\Validator({"name":"StringLength", "options":{"min":"5", "max":"255"}}) 
 
    * @Annotation\Filter({"name":"StripTags"}) 
 
    * @Annotation\Attributes({"class":"gui-input"}) 
 
    */ 
 
    private $metaDescription; 
 

 

use Zend\Form\Annotation\AnnotationBuilder; 
 
use DoctrineORMModule\Stdlib\Hydrator\DoctrineEntity; 
 

 
class IndexController extends AbstractAdminController { 
 

 
public function indexAction() { 
 
     
 
     $em = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager'); 
 
     
 
     $view = new ViewModel(); 
 
     
 
     $data = $this->getRequest()->getPost(); 
 
     $category = $em->getRepository('Application\Entity\BlogCategory')->findOneByName('tests'); 
 
     $builder = new AnnotationBuilder(); 
 
     $form  = $builder->createForm($category); 
 
     
 
     $form->setHydrator(new DoctrineEntity($em, false)); 
 
     
 
     $form->add(array(
 
      'type' => 'submit', 
 
      'name' => 'save', 
 
      'attributes' => array(
 
       'value' => 'Submit', 
 
      ) 
 
     )); 
 
     
 
     $form->bind($category); 
 
     $form->prepare(); 
 
     if ($this->getRequest()->isPost()){ 
 
      $form->setData($data); 
 
      if ($form->isValid()){    
 
       echo 'good!'; 
 
      }else{     
 
       echo 'bad'; 
 

 
      } 
 
     } 
 
     
 
     $view->setVariable('form', $form); 
 
     return $view;

enter image description here

Antwort

0

standardmäßig Lehre Beziehungen sind faul belastetes (Proxy) - sie sind nur dann geladen, wenn Elemente in der Auflistung tatsächlich abgerufen. Dies geschieht alles hinter den Kulissen, wenn Sie das tun:

Die letzte ist besonders wichtig. Sobald der Proxy durch das tatsächliche Objekt ersetzt wurde, wird das Objekt immer sofort zurückgegeben. Weitere Informationen zu Proxies finden Sie unter this question (empfohlen zum Lesen!)

Jetzt werden die Dinge etwas schwieriger bei der Verwendung von Hydratoren. Während der Extraktion ist die von getMetaContent zurückgegebene Referenz der PROXY. Aber der DoctrineEntity Hydrator löst den Proxy nicht auf, sondern überspringt ihn einfach als un-extractable. Genau das siehst du hier.

Warum hat es in erster Linie funktioniert, als Sie $category->getMetaContent()->getMetaDescription(); in Ihrem Controller hatten? Denn dadurch hat der Controller bereits dafür gesorgt, dass der Proxy durch das eigentliche Objekt ersetzt wurde! Jetzt empfängt der Hydrator anstelle des Proxys das eigentliche Objekt - welches es zu extrahieren weiß.

Um dem entgegenzuwirken, müssen Sie sicherstellen, dass der Proxy tatsächlich aufgelöst wird. Sie können dies auf zwei einfache Arten tun:

  • Tell Lehre zu EAGER load die Beziehung. Dadurch wird das Objekt MetaDescription immer sofort geladen. Beachten Sie, dass sich dies auf die Leistung auswirkt.
  • Registrieren Sie eine benutzerdefinierte Strategie mit dem Hydrator, der weiß, wie mit diesem Feld umzugehen ist (d. H. Es aus einem Proxy extrahieren). Siehe this question/answer für das gleiche Problem/Ansatz