Symfony SonataAdmin绑定链接字段(级联选择)
我正在尝试使用sonata管理包创建链接下拉列表 有 产品 产品类别多对多产品 与产品类别关联的产品功能基数:与产品关联的多对多和与类别关联的多对一,即一个类别可以有多个功能,但一个功能与一个类别关联 一切正常,一个“类别”字段的多选启用组合框和另一组“产品功能”字段的复选框正在使用此选项显示 在产品输入表格中:Symfony SonataAdmin绑定链接字段(级联选择),symfony,sonata-admin,Symfony,Sonata Admin,我正在尝试使用sonata管理包创建链接下拉列表 有 产品 产品类别多对多产品 与产品类别关联的产品功能基数:与产品关联的多对多和与类别关联的多对一,即一个类别可以有多个功能,但一个功能与一个类别关联 一切正常,一个“类别”字段的多选启用组合框和另一组“产品功能”字段的复选框正在使用此选项显示 在产品输入表格中: protected function configureFormFields(FormMapper $formMapper) { $formMapper
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('category', 'sonata_type_model', array('required' => false, 'expanded' => false, 'multiple' => true, 'label' => 'Choose your categories'))
->add('features', 'sonata_type_model', array('required' => false, 'expanded' => true, 'multiple' => true, 'label' => 'Choose Features'))
但我想要的是,当我在第一个组合(即类别)中选择值时,第二个复选框列表(即特征)应相应地动态加载,只有与该类别链接的特征
由于第一个选择框启用了多选功能,因此第二个列表是累积的将更好,即当选择类别1时,将显示与类别1相关的功能
然后,当选择类别2且同时选择类别1时,将显示与类别1和类别2相关的功能
我怎么做
我一直在谷歌上搜索,我找到的唯一好答案是这个2年前的解决方案,它看起来相当长而且有点陈旧。还有其他解决办法吗?在过去的两年中,事情一定发生了变化,因为在这段时间内发布了几个版本的sonata admin
有什么帮助吗?
提前谢谢。我在这方面有很多困难,但我想我找到了一个可行的解决办法。希望这能为将来节省一些时间 我的案例是:我有多个公司实体,有1到n个联系人实体。创建新职务时,我必须选择公司,然后我要按所选公司筛选联系人列表。正如你所看到的,它起作用了。根据所选公司,如果已加载联系人,则匹配列表: 为了让这一切顺利进行,我刚刚禁用了Customer和ContactPerson的映射标志,以便自己在postPersist中映射数据,并在我的admin类Extendes BaseAdmin中设置了postUpdate 然后,我为我的所有公司实体使用sonata_type_choice_field_mask。我自己构建了一个数据数组。之后,我使用sonata_type_模型,通过传递匹配的filter ContactPerson下拉列表,添加了一个预过滤 这是非常好的工作-但当然,它将失败,如果你有成千上万的公司和客户。在我的情况下,这不会发生,因此这是一个切实可行的解决方案 代码删除了不必要的内容:
<?php
namespace AppBundle\Admin;
use AppBundle\Entity\Customer;
use AppBundle\Entity\Job;
use AppBundle\Form\Types;
use AppBundle\Repository\CustomerRepository;
use AppBundle\Service\EntityManager;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Route\RouteCollection;
use Sonata\AdminBundle\Show\ShowMapper;
class JobAdmin extends BaseAdmin
{
const CONTACT_PERSON_DROPDOWN_PREFIX = 'contactPersons';
/**
* @param Job $job
* @return null|string
*/
protected function getPreselectedCustomerId(Job $job)
{
if ($job) {
$customer = $job->getCustomer();
if ($customer) {
$customerId = $customer->getId();
return $customerId;
}
}
return null;
}
/**
* @return \Doctrine\ORM\EntityRepository
*/
protected function getEnabledCustomers()
{
$customerRepository = $this->getCustomerRepository();
$customers = $customerRepository->findByEnabled();
return $customers;
}
/**
* @param $enabledCustomers
* @return array
*/
protected function getFilterMap($enabledCustomers)
{
$filterMap = [];
/**
* @var $customer Customer
*/
foreach ($enabledCustomers as $customer) {
$customerId = $customer->getId();
$fieldName = self::CONTACT_PERSON_DROPDOWN_PREFIX . $customerId;
$filterMap[$customerId] = [$fieldName];
}
return $filterMap;
}
/**
* @param $enabledCustomers
* @return array
*/
protected function getCustomerDropDown($enabledCustomers)
{
$customerDropDown = [];
/**
* @var $customer Customer
*/
foreach ($enabledCustomers as $customer) {
$customerId = $customer->getId();
$name = $customer->getName();
$customerDropDown[$name] = $customerId;
}
return $customerDropDown;
}
/**
* @param Customer $customer
* @return \Doctrine\ORM\QueryBuilder
*/
protected function getFilterQueryForCustomer(Customer $customer)
{
$entityManager = $this->getEntityManager();
$contactPersonQuery = $entityManager->createQueryBuilder('cp')
->select('cp')
->from('AppBundle:ContactPerson', 'cp')
->where('cp.customer = :customer')
->setParameter('customer', $customer)
->orderBy('cp.name', 'ASC')
;
return $contactPersonQuery;
}
/**
* @param FormMapper $formMapper
*/
protected function configureFormFields(FormMapper $formMapper)
{
$job = $this->getSubject();
$enabledCustomers = $this->getEnabledCustomers();
$filterMap = $this->getFilterMap($enabledCustomers);
$customerDropDown = $this->getCustomerDropDown($enabledCustomers);
$preselectedId = $this->getPreselectedCustomerId($job);
$formMapper
->tab('BaseData')
->with('JobData')
->add('customer', 'sonata_type_choice_field_mask', array(
'choices' => $customerDropDown,
'data' => $preselectedId,
'map' => $filterMap,
'by_reference' => false,
'required' => true,
'mapped' => false,
)
)
->end()
->end()
;
/**
* @var $customer Customer
*/
foreach ($enabledCustomers as $customer) {
$customerId = $customer->getId();
$fieldName = self::CONTACT_PERSON_DROPDOWN_PREFIX . $customerId;
$filterQuery = $this->getFilterQueryForCustomer($customer);
$formMapper
->tab('BaseData')
->with('JobData')
->add($fieldName, 'sonata_type_model', array(
'class' => 'AppBundle\Entity\ContactPerson',
'query' => $filterQuery,
'mapped' => false,
'label' => 'Contact Person'
))
->end()
->end()
;
}
$formMapper
->tab('BaseData')
->with('JobData')
->add('name')
// Add more fields
->end()
->end()
;
}
/**
* @param EntityManager $entityManager
* @return \Doctrine\ORM\EntityRepository
*/
protected function getCustomerRepository(EntityManager $entityManager = null)
{
if (!$entityManager) {
$entityManager = $this->getEntityManager();
}
$customerRepository = $entityManager->getRepository(Customer::class);
return $customerRepository;
}
/**
* @return EntityManager
*/
protected function getEntityManager()
{
$entityManager = $this->getConfigurationPool()->getContainer()->get('doctrine')->getManager();
return $entityManager;
}
/**
* @param Job $job
*/
protected function mapUnmappedFields (Job $job)
{
$customerId = $this->getForm()->get('customer')->getData();
if ($customerId)
{
$entityManager = $this->getEntityManager();
$contactPerson = $this->getForm()->get(self::CONTACT_PERSON_DROPDOWN_PREFIX.$customerId)->getData();
$customerRepository = $this->getCustomerRepository($entityManager);
$customer = $customerRepository->findById($customerId);
if ($contactPerson) {
$job->setContactPerson($contactPerson);
}
if ($customer) {
$job->setCustomer($customer);
}
$entityManager->persist($job);
$entityManager->flush($job);
}
}
/**
* @param mixed $object
*/
public function postPersist($object)
{
$this->mapUnmappedFields($object);
parent::postPersist($object);
}
/**
* @param mixed $object
*/
public function postUpdate($object)
{
$this->mapUnmappedFields($object);
parent::postUpdate($object);
}
}
不管怎样,我终于自己解决了这个问题。这个问题给我赢得了一枚风滚草徽章。但是,如果有人需要它,可以打我。嗨,你是如何解决这个问题的,thanks@TheGooooogle很高兴知道你是如何处理这个案子的。