如何使用数据变形金刚吗
编辑该页面警告:你浏览的文档欧宝官网下载appob娱乐下载Symfony 2.8,不再维护。
读这个页面的更新版本Symfob娱乐下载ony 6.2(当前的稳定版本)。
如何使用数据变形金刚吗
数据变压器用于将一个字段的数据转化为一个格式,可以显示在一个表单(并重新提交)。他们已经在内部使用了许多字段类型。例如,DateType字段可以呈现为一个yyyy-MM-dd
格式化的输入框中。在内部,一个数据变压器转换开始DateTime
领域进入的价值yyyy-MM-dd
字符串的形式呈现,然后回一个DateTime
在提交对象。
谨慎
当一个表单字段inherit_data
选项设置,数据变压器不会被应用到这一领域。
简单的例子:从用户输入字符串标记转换为一个数组
假设你有一个任务形式标记文本
类型:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21日22日23日24日25
/ / src / AppBundle / /类型/ TaskType.php形式名称空间AppBundle\形式\类型;使用AppBundle\实体\任务;使用ob娱乐下载\组件\形式\FormBuilderInterface;使用ob娱乐下载\组件\OptionsResolver\OptionsResolver;使用ob娱乐下载\组件\形式\扩展\核心\类型\TextType;/ /……类TaskType扩展AbstractType{公共函数buildForm(FormBuilderInterface美元构建器数组,美元选项){美元构建器- >add (“标签”,TextType::类);}公共函数configureOptions(OptionsResolver美元解析器){美元解析器- >setDefaults (数组(“data_class”= >任务::类);}/ /……}
在内部的标签
被存储为一个数组,但显示给用户一个简单的逗号分隔字符串,使它们更容易编辑。
这是一个完美的将自定义数据变压器附加到的时间标签
字段。这是最简单的方法CallbackTransformer类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27 28 29 30
/ / src / AppBundle / /类型/ TaskType.php形式名称空间AppBundle\形式\类型;使用ob娱乐下载\组件\形式\CallbackTransformer;使用ob娱乐下载\组件\形式\FormBuilderInterface;使用ob娱乐下载\组件\形式\扩展\核心\类型\TextType;/ /……类TaskType扩展AbstractType{公共函数buildForm(FormBuilderInterface美元构建器数组,美元选项){美元构建器- >add (“标签”,TextType::类);美元构建器- >get (“标签”)- >addModelTransformer (新CallbackTransformer (函数(美元tagsAsArray){/ /数组转换成一个字符串返回内爆(”、“,美元tagsAsArray);},函数(美元tagsAsString){/ /将字符串返回一个数组返回爆炸(”、“,美元tagsAsString);}));}/ /……}
的CallbackTransformer
有两个回调函数作为参数。首先将原始值转换成格式,将用于呈现。第二个效果恰恰相反:它将提交的值回在代码中您将使用的格式。
提示
的addModelTransformer ()
方法接受任何对象实现DataTransformerInterface——所以您可以创建自己的类,而不是把所有的逻辑形式(参见下一节)。
您还可以添加变压器,当添加字段通过改变格式略:
1 2 3 4 5 6 7
使用ob娱乐下载\组件\形式\扩展\核心\类型\TextType;美元构建器- >add (美元构建器- >创建(“标签”,TextType::类)- >addModelTransformer (…));
困难的例子:将一个问题数量转变为一个实体问题
说你有多对一关系从任务的实体问题的实体(即每个任务都有一个可选的外键对其相关问题)。添加一个列表框与所有可能的问题最终会得到真的长,需要很长时间才能加载。相反,你决定你想添加一个文本框,用户可以输入号码的问题。
首先设置文本框像正常:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27
/ / src / AppBundle / /类型/ TaskType.php形式名称空间AppBundle\形式\类型;使用AppBundle\实体\任务;使用ob娱乐下载\组件\形式\扩展\核心\类型\TextareaType;使用ob娱乐下载\组件\形式\扩展\核心\类型\TextType;/ /……类TaskType扩展AbstractType{公共函数buildForm(FormBuilderInterface美元构建器数组,美元选项){美元构建器- >add (“描述”,TextareaType::类)- >add (“问题”,TextType::类);}公共函数configureOptions(OptionsResolver美元解析器){美元解析器- >setDefaults (数组(“data_class”= >任务::类);}/ /……}
好的开始!但是如果你停止在这里,提交了表单,任务的问题
属性将一个字符串(如。“55”)。你怎么能把这变成一个问题
实体提交吗?
创建一个变压器
你可以用CallbackTransformer
就像早些时候。但由于这是一个更复杂的,创建一个新的变压器类的TaskType
类更简单的形式。
创建一个IssueToNumberTransformer
类:它将负责号码和转换的问题问题
对象:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
/ / src / AppBundle /形式/ DataTransformer / IssueToNumberTransformer.php名称空间AppBundle\形式\DataTransformer;使用AppBundle\实体\问题;使用学说\常见的\持久性\ObjectManager;使用ob娱乐下载\组件\形式\DataTransformerInterface;使用ob娱乐下载\组件\形式\异常\TransformationFailedException;类IssueToNumberTransformer实现了DataTransformerInterface{私人美元objectManager;公共函数__construct(ObjectManager美元objectManager){美元这- >objectManager =美元objectManager;}/ * * *转换对象(问题),一个字符串(数值)。”* *@param*问题|零美元问题@return字符串* /公共函数变换(美元问题){如果(零= = =美元问题){返回”;}返回美元问题- >getId ();}/ * * *转换字符串(数量)一个对象(问题)。* *@param字符串$ issueNumber *@return问题|零*@throws没有找到TransformationFailedException如果对象(问题)。* /公共函数reverseTransform(美元issueNumber){/ /没有问题号码吗?这是可选的,所以没关系如果(!美元issueNumber){返回;}美元问题=美元这- >objectManager- >getRepository(问题::类)/ /查询这个id的问题- >找到(美元issueNumber);如果(零= = =美元问题){/ /验证错误原因/ /这个信息没有显示给用户/ /看到invalid_message选项扔新TransformationFailedException (sprintf (的数量的问题“% s”不存在!”,美元issueNumber));}返回美元问题;}}
就像在第一个例子中,一个变压器有两个方向。的变换()
方法负责将在代码中使用的数据转换为一种格式,可以呈现在表单(例如一个问题
对象的id
一个字符串)。的reverseTransform ()
方法的效果恰恰相反:它转换回你想要的格式提交的值(例如转换id
回问题
对象)。
导致验证错误,抛出一个TransformationFailedException。但消息传递给这个例外不会显示给用户。你会设置的消息invalid_message
选项(见下文)。
请注意
当零
传递给变换()
方法,你的变压器应该返回一个等价的值的类型是改变(如一个空字符串,0为整数或0.0浮动)。
使用变压器
接下来,您需要实例化IssueToNumberTransformer
内部类TaskType
并将其添加到问题
字段。但要做到这点,你需要实体管理器的一个实例(因为IssueToNumberTransformer
需要这个)。
没问题!只是添加一个__construct ()
函数TaskType
,这是在通过注册通过TaskType
作为一个服务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27 28 29 30 31 32 33 34 35
/ / src / AppBundle / /类型/ TaskType.php形式名称空间AppBundle\形式\类型;使用AppBundle\形式\DataTransformer\IssueToNumberTransformer;使用学说\常见的\持久性\ObjectManager;使用ob娱乐下载\组件\形式\扩展\核心\类型\TextareaType;使用ob娱乐下载\组件\形式\扩展\核心\类型\TextType;/ /……类TaskType扩展AbstractType{私人美元objectManager;公共函数__construct(ObjectManager美元objectManager){美元这- >objectManager =美元objectManager;}公共函数buildForm(FormBuilderInterface美元构建器数组,美元选项){美元构建器- >add (“描述”,TextareaType::类)- >add (“问题”,TextType::类,数组(/ /验证消息如果数据变压器失败“invalid_message”= >“这不是一个有效的问题数量”));/ /……美元构建器- >get (“问题”)- >addModelTransformer (新IssueToNumberTransformer (美元这- >objectManager));}/ /……}
定义表单类型作为服务在您的配置文件。
- YAML
- XML
- PHP
1 2 3 4 5 6 7
# src / AppBundle /资源/ config / services.yml服务:app.form.type.task:类:AppBundle \ \ \ TaskType型形式参数:(“@doctrine.orm.entity_manager”)标签:- - - - - -{名称:form.type}
提示
关于表单类型定义为服务的更多信息,阅读注册表单类型作为服务。
现在,你可以很容易地用你的TaskType
:
1 2 3 4
/ /例如控制器在一个地方美元形式=美元这- >createForm (TaskType::类,美元任务);/ /……
酷,你已经完成了!用户可以在文本框中输入一个问题数量,它将被转换回一个问题对象。这意味着,提交成功后,表单组件将通过一个真实的问题
对象任务::setIssue ()
而不是数量的问题。
如果这个问题没有发现,将会创建一个形状误差对该字段及其错误消息可以控制的invalid_message
场的选择。
谨慎
添加时要小心你的变形金刚。例如,下面是错误的,随着变压器将应用于整个表单,而不是仅仅这一领域:
1 2 3 4
/ /这是错误的——变压器将适用于整个表单/ /上面看到正确的代码示例美元构建器- >add (“问题”,TextType::类)- >addModelTransformer (美元变压器);
创建一个可重用issue_selector字段
在上面的示例中,您使用变压器正常文本
字段。但是如果你这个变换,它可能是更好的创建一个自定义字段类型。自动做这个。
首先,创建自定义字段类型类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27 28 29 30 31 32 33 34 35 36
/ / src / AppBundle /形式/ IssueSelectorType.php名称空间AppBundle\形式;使用AppBundle\形式\DataTransformer\IssueToNumberTransformer;使用学说\常见的\持久性\ObjectManager;使用ob娱乐下载\组件\形式\AbstractType;使用ob娱乐下载\组件\形式\FormBuilderInterface;使用ob娱乐下载\组件\OptionsResolver\OptionsResolver;类IssueSelectorType扩展AbstractType{私人美元objectManager;公共函数__construct(ObjectManager美元objectManager){美元这- >objectManager =美元objectManager;}公共函数buildForm(FormBuilderInterface美元构建器数组,美元选项){美元变压器=新IssueToNumberTransformer (美元这- >objectManager);美元构建器- >addModelTransformer (美元变压器);}公共函数configureOptions(OptionsResolver美元解析器){美元解析器- >setDefaults (数组(“invalid_message”= >“不存在选择的问题”));}公共函数getParent(){返回TextType::类;}}
太棒了!这将呈现像文本字段(getParent ()
),但会自动数据变压器和一个默认值invalid_message
选择。
接下来,注册您的类型作为服务和标签form.type
所以它是公认的一个自定义字段类型:
- YAML
- XML
- PHP
1 2 3 4 5 6 7
# app / config / services.yml服务:app.type.issue_selector:类:AppBundle \ \ IssueSelectorType形式参数:(“@doctrine.orm.entity_manager”)标签:- - - - - -{名称:form.type}
现在,当你需要使用你的特别issue_selector
字段类型,它很简单:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/ / src / AppBundle / /类型/ TaskType.php形式名称空间AppBundle\形式\类型;使用AppBundle\形式\IssueSelectorType;使用ob娱乐下载\组件\形式\扩展\核心\类型\TextareaType;/ /……类TaskType扩展AbstractType{公共函数buildForm(FormBuilderInterface美元构建器数组,美元选项){美元构建器- >add (“描述”,TextareaType::类)- >add (“问题”,IssueSelectorType::类);}/ /……}
模型和视图变形金刚
在上面的例子中,变压器被用作变压器“模型”。事实上,有两个不同类型的变压器和三种不同类型的基础数据。
在任何形式,三种不同类型的数据:
- 模型数据——这是在应用程序中使用的数据格式(如一个
问题
对象)。如果你叫形式::getData ()
或形式::setData ()
,你在处理“模型”的数据。 - 规范数据——这是一个规范化的版本你的数据和通常一样的“模型”数据(虽然不是在我们的示例中)。它不是常用的直接。
- 视图数据——这是用来填写表单字段的格式,自己。这也是用户提交数据的格式。当你打电话
形式:提交(元数据)
,元数据
在“视图”数据格式。
两种不同类型的变压器帮助转换与每一种类型的数据:
- 变形金刚模型:
-
变换()
:“模型数据”= >“规范数据”reverseTransform ()
:“规范数据”= >“模型数据”
- 看变形金刚:
-
变换()
:“规范数据”= >“查看数据”reverseTransform ()
:“查看数据”= >“规范数据”
变压器需要取决于您的情况。
使用视图变压器,电话addViewTransformer ()
。
为什么使用模型的变压器?
在这个例子中,字段是一个文本
领域,一个文本字段总是将一个简单的、标量格式在“规范”和“视图”格式。出于这个原因,“模型”是最合适的变压器变压器(的/转换规范格式-字符串问题数字的模型格式-问题对象)。
变压器的区别是微妙的,你应该考虑的“常态”数据字段应该是。例如,“规范”的数据文本
字段是一个字符串,但是是一个DateTime
对象的一个日期
字段。
提示
作为一般规则,规范化数据应该包含尽可能多的信息。