Bor*_*mbo 5 symfony-forms symfony form-fields sonata-admin sonata
我正在尝试在首页上插入自定义奏鸣曲表单字段类型,而不是在 SonataAdmin 中,如下所示:
$form = $this->createFormBuilder($content)
->add('titleEs', 'text', array('required' => true, 'label' => 'label.title.spanish', 'attr' => array('class' => 'col-xs-12 form-control input-lg')))
->add('contentEs', 'ckeditor', array('required' => true,'label' => 'label.content.spanish', 'attr' => array('class' => 'col-xs-12')))
->add('titleEn', 'text', array('required' => true,'label' => 'label.title.english', 'attr' => array('class' => 'col-xs-12 form-control input-lg')))
->add('contentEn', 'ckeditor', array('required' => true, 'label' => 'label.content.english', 'attr' => array('class' => 'col-xs-12')))
->add('header', 'sonata_type_model', array('required' => true,'label' => 'label.content.headerImage'), array('link_parameters' => array('context' => 'content/front', 'size' => 'big')))
//->add('coverImage', 'sonata_type_model_list', array('required' => true,'label' => 'label.content.coverImage'), array('link_parameters' => array('context' => 'content/front', 'size' => 'small')))
//->add('sliderImage', 'sonata_type_model_list', array('required' => false,'label' => 'label.content.sliderImage'), array('link_parameters' => array('context' => 'content/slider', 'size' => 'normal')))
->getForm();
Run Code Online (Sandbox Code Playgroud)
但是当我执行它时,它会抛出一个错误:
Catchable Fatal Error: Argument 1 passed to Sonata\AdminBundle\Form\ChoiceList\ModelChoiceList::__construct() must implement interface Sonata\AdminBundle\Model\ModelManagerInterface, null given
Run Code Online (Sandbox Code Playgroud)
如果奏鸣曲表单字段类型是服务,我不明白为什么 Symfony 会抛出该错误。
感谢 @gabtzi 的回答,我查阅了 Sonata Admin 的源代码,并提出了一个非常相似的解决方案。假设我们有两个实体Movie
,并且Genre
它们之间具有多对多关系(Movie
是拥有方),Symfony 4 和 Sonata Admin 3.x 中的解决方案将如下所示:
<?php
namespace App\Form\Type;
use App\Entity\Movie;
use App\Entity\Genre;
use Symfony\Component\Form\AbstractType;
use Sonata\AdminBundle\Form\Type\ModelType;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class MovieType extends AbstractType
{
private $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
// add fields
->add('genres', ModelType::class, [
'multiple' => true,
'class' => Genre::class,
'property' => 'name', // assuming Genre has property name
'model_manager' => $this->container->get('sonata.admin.manager.orm'),
'by_reference' => false
])
// add more fields
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Movie::class,
));
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个非常基本的示例,但应该给出如何进一步进行的想法。重要的是:
如果您使用自动装配,则不必将表单类型注册为服务。检查您autowire
的. 阅读官方文档了解更详细的信息;true
config/services.yaml
传递ContainerInterface
给构造函数以获取容器;
你不再使用了sonata_type_model
。你必须使用ModelType::class
. 注意使用语句;
您可以将M2M 关系设置mutiple
为,否则默认为;true
false
你必须将实体类传递给class
- 在这种情况下Movie::class
;
您可以指定property
使用 的某些属性Genre
。__toString
如果您在实体类中定义了方法,则不必声明此方法。然后会使用这个方法的返回值;
最重要的是:现在您已经有了容器,获取服务sonata.admin.manager.orm
并将其传递给model_manager
. 没有这个,一切都会陷入水中。
然而我还没有设法显示该按钮+ Add new。值得一提的是,相关属性的管理类必须存在并且可访问(设置适当的权限) - 在这种情况下GenreAdmin
将是必需的,否则该按钮在理论上甚至无法工作。
归档时间: |
|
查看次数: |
1755 次 |
最近记录: |