Symfony 2如何查找自定义表单类型? [英] How does Symfony 2 find custom form types?

查看:101
本文介绍了Symfony 2如何查找自定义表单类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读数据转换,我稍稍修改了我的代码我正在获得


无法加载类型csv2tags


我有一个自定义表单类型

  class CSV2TagsType extends AbstractType {
public function buildForm(FormBuilder $构建器,数组$ opts){
$ builder-> appendClientTransformer(new CSV2TagsTransformer());
}
public function getParent(){
return'text';
}
public function getName(){
return'csv2tags';
}
}

使用变压器:

  class CSV2TagsTransformer实现DataTransformerInterface {
/ **
* @var EntityManager
* /
protected $ em ;
public function __construct(EntityManager $ em){
$ this-> em = $ em;
}
// ...
}

code> services.yml

 服务:
jm.blog.csv2tagsTransformer :
class:JM\BlogBu​​ndle\Form\DataTransformer\CSV2TagsTransformer
arguments:[@ doctrine.orm.entity_manager]

几个问题:




  • 我移动了 EntityManager 到变压器而不是表单类型,是吗?

  • 我没有在文档中声明变压器服务的别名。我认为表单类型的别名来自于 AbstractType :: getName()函数?我需要将自定义表单类型声明为服务

  • 我将 EntityManager 移动到变压器。当我做了新的CSV2TagsTransformer()而没有 EntityManager 时,我做了正确的事情?


解决方案

我将完成@ greg0ire给出的答案,这几乎是正确的。 p>

首先,您定义的服务应该是您的表单类型( CSV2TagsType )而不是您的变压器( CSV2TagsTransformer ),因为它是表单构建器使用的表单类型。由于表单构建器希望使用 AbstractType ,因为数据变换器不是 AbstractType 。如@ greg0ire所说,您必须使用 form.type 标签来标记自定义表单类型。

 服务:
jm.blog.csv2tagsType:
class:JM\BlogBu​​ndle\Form\Type\CSV2TagsType
arguments:[@ doctrine.orm。 entity_manager]
标签:
- {name:form.type,别名:csv2tags}

您的自定义表单类型中的函数 getName 返回的值必须与您给出的别名( cvs2tags )或您定义的服务标识( jm.blog.csv2tagsType )。这是Symfony可以找到您的自定义类型的方式。它尝试找到由 getName()方法给出的服务标识。



对于您的数据变压器,有一个小问题你正在做新的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));
}

//其他类
}

这样,您将实体管理器注入到表单类型中,这可能是因为表单类型被定义为服务。在表单类型中,您实例化数据变换器,并传递给已注入表单类型的实体管理器。



另一种方法是也声明您将数据变压器作为服务,然后将其注入到表单类型中。这样,您不需要自己实例化一个数据变换器,而是使用在表单类型的构造函数中注入的变量。因此,如果您不需要表单类型的实体管理器,则可以省略注入。这里有一个例子:

  services:
jm.blog.csv2tagsTransformer:
class:JM \BlogBu​​ndle\Form\DataTransformer\CSV2TagsTransformer
参数:[@ doctrine.orm.entity_manager]

jm.blog.csv2tagsType:
class:JM\\ \\ BlogBu​​ndle\Form\Type\CSV2TagsType
参数:[@ jm.blog.csv2tagsTransformer]
标签:
- {name:form.type,别名: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);
}

//其他类
}

这里有一个关于你的问题答案的小简历:


  1. 这是正确的。

  2. 变压器服务不需要别名。但是,如@ greg0ire所说,您需要为表单类型定义一个服务。 getName()函数必须返回应该使用的id。它可以是定义的别名,也可以是服务标识。通常,人们使用别名作为 getName 返回的值。

  3. 执行新增功能是不正确的CSV2TagsTransformer()因为这样,你不会将实体管理器发送到你的类,并且由于它不能接受null值,它将在PHP中失败。

  4. <

    希望这有帮助。



    请问,
    Matt


    I was reading up of Data Transformations I modified it somewhat in my code. I am getting

    Could not load type "csv2tags"

    I have a custom form type

    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';
        }
    }
    

    Using the transformer:

    class CSV2TagsTransformer implements DataTransformerInterface {
        /**
         * @var EntityManager
         */
        protected $em;
        public function __construct(EntityManager $em) {
            $this->em = $em;
        }
        // ... 
    }
    

    In services.yml

    services:
        jm.blog.csv2tagsTransformer:
            class: JM\BlogBundle\Form\DataTransformer\CSV2TagsTransformer
            arguments: ["@doctrine.orm.entity_manager"]
    

    A few questions:

    • I moved EntityManager to the transformer instead of the form type, is that OK?
    • I didn't declare an alias for the transformer service like in the docs. I thought the alias for the form type was from the AbstractType::getName() function? Do I need to declare my custom form type as a service too
    • I moved the EntityManager to the transformer. Did I do the right thing when I did new CSV2TagsTransformer() without the EntityManager?

    解决方案

    I will just complete the answer given by @greg0ire which is almost right.

    First, the service you defined should be your form type (CSV2TagsType) and not your transformer (CSV2TagsTransformer) because it is the form type that is used by the form builder. Since the form builder expect an AbstractType, it will not work with your service definition since the data transformer is not an AbstractType. As @greg0ire said, you must tag your custom form type with the form.type tag.

    services:
      jm.blog.csv2tagsType:
        class: JM\BlogBundle\Form\Type\CSV2TagsType
        arguments: ["@doctrine.orm.entity_manager"]
        tags:
          - { name: form.type, alias: csv2tags }
    

    The value returned by the function getName in your custom form type must match the alias you gave (cvs2tags) or the service id you defined (jm.blog.csv2tagsType). This is the way Symfony can find your custom type. It tries to find the service id given by the getName() method.

    For you data transformer, there is a litte problem. You are doing new CSV2TagsTransformer() but you are not passing the entity manager. This will result in an error. You cannot do it this way because there is no way to inject the data transformer in a service way.

    What you need to do is to inject the entity manager in you custom form type and then pass it to the data transformer when you instantiate it.

    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
    }
    

    This way, you inject the entity manager in your form type, which is possible because the form type is defined as a service. And in the form type, you instantiate the data transformer and pass to the construct the entity manager that have been injected into the form type.

    Another way to go would be to also declare you data transformer as a service and then inject it in the form type. This way, you do not instantiate a data transformer yourself but you use the one injected in the constructor of the form type. So, if you don't need the entity manager in the form type, you can omit to inject it. Here an example of this alternative:

    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
    }
    

    Here a small resume of the answers to your question:

    1. It is correct.
    2. No alias is needed for the transformer service. But as @greg0ire said, you need to define a service for you form type. The getName() function must returned the id that should be used. It can be the alias defined, or the service id directly. Usually, people use the alias as the value returned by getName.
    3. It is not correct to do new CSV2TagsTransformer() because this way, you a not sending the entity manager to your class and since it can't accept null value, it will fail in PHP.

    Hope this helps.

    Regards,
    Matt

    这篇关于Symfony 2如何查找自定义表单类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆