簡體   English   中英

SonataAdmin和Symfony2中的一對多關系和添加/編輯表單

[英]One to Many relations and add/edit form in SonataAdmin and Symfony2

我有一個包含兩個實體的簡單Symfony2應用程序:Municipality和Poi。 市與Pois之間存在“一對多”關系(即:在一個市中放置零個或更多pois),因此實體文件如下所示:

POC \\ PocBundle \\實體\\ Municipality.php

<?php

// Poc\PocBundle\Entity\Municipality.php

namespace Poc\PocBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Municipality
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Poc\PocBundle\Entity\MunicipalityRepository")
 */
class Municipality
{
    /**
     * @ORM\OneToMany(targetEntity="Poi", mappedBy="municipality")
     */
    protected $pois;

    public function __construct()
    {
        $this->pois = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;


    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Municipality
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Add pois
     *
     * @param \Poc\PocBundle\Entity\Poi $pois
     * @return Municipality
     */
    public function addPois(\Poc\PocBundle\Entity\Poi $pois)
    {
        $this->pois[] = $pois;

        return $this;
    }

    /**
     * Remove pois
     *
     * @param \Poc\PocBundle\Entity\Poi $pois
     */
    public function removePois(\Poc\PocBundle\Entity\Poi $pois)
    {
        $this->pois->removeElement($pois);
    }

    /**
     * Get pois
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getPois()
    {
        return $this->pois;
    }

    public function __toString()
    {
        return $this->name;
    }
}

POC \\ PocBundle \\實體\\ Poi.php

<?php

// Poc\PocBundle\Entity\Poi.php

namespace Poc\PocBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Poi
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Poc\PocBundle\Entity\PoiRepository")
 */
class Poi
{
    /**
     * @ORM\ManyToOne(targetEntity="Municipality", inversedBy="pois")
     * @ORM\JoinColumn(name="municipality_id", referencedColumnName="id")
     */
    protected $municipality;

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;


    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Poi
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set municipality
     *
     * @param \Poc\PocBundle\Entity\Municipality $municipality
     * @return Poi
     */
    public function setMunicipality(\Poc\PocBundle\Entity\Municipality $municipality = null)
    {
        $this->municipality = $municipality;

        return $this;
    }

    /**
     * Get municipality
     *
     * @return \Poc\PocBundle\Entity\Municipality 
     */
    public function getMunicipality()
    {
        return $this->municipality;
    }

    public function __toString()
    {
        return $this->name;
    }
}

在這一點上,我想通過Sonata Admin中的“市政添加/編輯”表單來管理市政與市政局之間的一對多關系。

我已經按照http://sonata-project.org/bundles/doctrine-orm-admin/master/doc/reference/form_field_definition.html#advanced-usage-one-to-many中的說明進行了操作,因此,MunicipalityAdmin類文件是:

POC / PocBundle /管理/ MunicipalityAdmin.php

<?php
namespace Poc\PocBundle\Admin;

use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Show\ShowMapper;

class MunicipalityAdmin extends Admin
{
    protected function configureListFields(ListMapper $listMapper)
    {
        $listMapper
            ->addIdentifier('name')
            ->add('_action', 'actions', array(
                'actions' => array(
                    'show' => array(),
                    'edit' => array(),
                )
            ))
        ;
    }
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('name')
            ->add('pois', 'sonata_type_collection', array(), array(
                'edit' => 'inline',
                'inline' => 'table',
                'sortable'  => 'position'
            ))
    ;
    }
}

我要獲取的表單是一個添加/編輯表單,我可以在其中定義市政當局的名稱,並從Poi實體中添加/刪除相關的Pois,但實際上,我得到的是一種可以定義市政當局的名稱的表單,並以一種子形式管理Poi實體。

此屏幕快照描述了結果-> http://i.imgur.com/nM1ywwh.png

我的意思是,通過這種方式,我可以添加新的Pois以及與任何市政當局(即洛杉磯)的關系,但是我要獲取的是與此市政當局有關的al pois列表,並且可以:

  • 添加新關系(即:將像自由女神像這樣的孤兒Poi與該市(紐約)聯系起來)。
  • 刪除現有關系(即:刪除不正確的關系,例如紐約的“沃爾特迪斯尼音樂廳”)

我已經看到了相反的管理方式,可以在Poi添加/編輯表單(多對一)中選擇與每個Poi相關的自治市,但是我想知道是否有任何方法可以在其他實體。

我可以在SonataAdmin中這樣做嗎? 有什么線索嗎?

更新:解決了用戶界面並添加了pois,但未刪除

通過以這種方式定義表單,我已經可以顯示想要的小部件了:

protected function configureFormFields(FormMapper $formMapper)
{
    $formMapper
        ->add('name')
        ->add('pois', null, array(), array(
            'edit' => 'inline',
            'inline' => 'table',
            'sortable'  => 'position'
        ))
;
}

我所做的是將“ sonata_type_collection”更改為空值。 現在,我得到了這樣的屏幕截圖-> 正確的表格GUI

...這只是我想要的行為。

最初,此小部件中的添加項(即:向市政當局添加新的pois)並未持久。 多虧了Radomir Wojtera的評論,我才意識到我的市級實體類(setPois,addPoi和removePoi)中沒有實現一些方法。

我添加了這種方法...

public function setPois($pois)
{
    if (count($pois) > 0) {
        foreach ($pois as $i) {
            $this->addPoi($i);
        }
    }

    return $this;
}

public function addPoi(\Poc\PocBundle\Entity\Poi $poi)
{
    $poi->setMunicipality($this);
    $this->pois->add($poi);
}

public function removePoi(\Poc\PocBundle\Entity\Poi $poi)
{
    $this->pois->removeElement($poi);
}

...現在我可以為市政當局獲得新的Pois,但是當我刪除一些Pois時,它們並沒有分離。 因此我可以添加關系,但不能刪除關系。

最后,我可以通過在實體配置中設置orphanRemoval = true來解決第二個問題(從市政當局刪除Poi無效)

class Municipality
{
    /**
     * @ORM\OneToMany(targetEntity="Poi", mappedBy="municipality", cascade={"persist"}, orphanRemoval=true))
     */
    protected $pois;
...

如問題更新中所述,第一個問題已解決。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM