我正在阅读Data Transformations我在代码中对其进行了一些修改。我正在
无法加载类型“csv2tags”
我有自定义表单类型
class CSV2TagsType extends AbstractType {
public function buildForm(FormBuilder $builder, array $opts) {
$builder->appendClientTransformer(new CSV2TagsTransformer());
}
public function getParent() {
return 'text';
}
public function getName() {
return 'csv2tags';
}
}
使用变压器:
class CSV2TagsTransformer implements DataTransformerInterface {
/**
* @var EntityManager
*/
protected $em;
public function __construct(EntityManager $em) {
$this->em = $em;
}
// ...
}
在services.yml
services:
jm.blog.csv2tagsTransformer:
class: JM\BlogBundle\Form\DataTransformer\CSV2TagsTransformer
arguments: ["@doctrine.orm.entity_manager"]
几个问题:
EntityManager
移到变换器而不是表单类型,是吗?AbstractType::getName()
函数?我是否需要将自定义表单类型声明为服务EntityManager
移到变压器上。当我new CSV2TagsTransformer()
没有EntityManager
时,我做了正确的事吗? 答案 0 :(得分:3)
我将完成@ greg0ire给出的答案,这几乎是正确的。
首先,您定义的服务应该是您的表单类型(CSV2TagsType
)而不是您的转换器(CSV2TagsTransformer
),因为它是表单构建器使用的表单类型。由于表单生成器需要AbstractType
,因此它不适用于您的服务定义,因为数据转换器不是AbstractType
。正如@ greg0ire所说,您必须使用form.type
标记标记自定义表单类型。
services:
jm.blog.csv2tagsType:
class: JM\BlogBundle\Form\Type\CSV2TagsType
arguments: ["@doctrine.orm.entity_manager"]
tags:
- { name: form.type, alias: csv2tags }
自定义表单类型中函数getName
返回的值必须与您提供的别名(cvs2tags
)或您定义的服务ID(jm.blog.csv2tagsType
)相匹配。这是Symfony可以找到您的自定义类型的方式。它试图找到getName()
方法给出的服务ID。
对于您的数据转换器,存在一个小问题。您正在执行new CSV2TagsTransformer()
,但您没有通过实体管理器。这将导致错误。你不能这样做,因为无法以服务方式注入数据转换器。
您需要做的是以自定义表单类型注入实体管理器,然后在实例化时将其传递给数据转换器。
class CSV2TagsType extends AbstractType
{
protected $em;
public function __construct(EntityManager $em) {
$this->em = $em;
}
public function buildForm(FormBuilder $builder, array $opts) {
$builder->appendClientTransformer(new CSV2TagsTransformer($this->em));
}
// Rest of class
}
这样,您可以在表单类型中注入实体管理器,这是可能的,因为表单类型被定义为服务。在表单类型中,您实例化数据转换器并将已注入表单类型的实体管理器传递给构造。
另一种方法是将数据转换器声明为服务,然后将其注入表单类型。这样,您不会自己实例化数据转换器,而是使用在表单类型的构造函数中注入的数据转换器。因此,如果您不需要表单类型中的实体管理器,则可以省略注入它。这是另一个例子:
services:
jm.blog.csv2tagsTransformer:
class: JM\BlogBundle\Form\DataTransformer\CSV2TagsTransformer
arguments: ["@doctrine.orm.entity_manager"]
jm.blog.csv2tagsType:
class: JM\BlogBundle\Form\Type\CSV2TagsType
arguments: ["@jm.blog.csv2tagsTransformer"]
tags:
- { name: form.type, alias: csv2tags }
class CSV2TagsType extends AbstractType
{
protected $transformer;
public function __construct(CSV2TagsTransformer $transformer) {
$this->transformer= $transformer;
}
public function buildForm(FormBuilder $builder, array $opts) {
$builder->appendClientTransformer($this->transformer);
}
// Rest of class
}
这是您问题答案的小简历:
getName()
函数必须返回应该使用的id。它可以是定义的别名,也可以是服务ID。通常,人们使用别名作为getName
返回的值。new CSV2TagsTransformer()
是不正确的,因为这样,您不会将实体管理器发送到您的类,因为它不能接受空值,所以它将在PHP中失败。希望这有帮助。
的问候,
马特
答案 1 :(得分:1)
关于您的主要问题,在services.yml
文件中,您应该将服务标记为form.type
,如下所示:
services:
jm.blog.csv2tagsTransformer:
class: JM\BlogBundle\Form\DataTransformer\CSV2TagsTransformer
arguments: ["@doctrine.orm.entity_manager"]
tags:
- { name: form.type, alias: csv2tags }
对于其他问题,我不知道。