@@ -78,18 +78,23 @@ one of the values is changed.
78
78
79
79
The red, green and blue form fields have to be mapped to the constructor
80
80
arguments and the ``Color `` instance has to be mapped to red, green and blue
81
- form fields. Recognize a familiar pattern? It's time for a data mapper::
81
+ form fields. Recognize a familiar pattern? It's time for a data mapper. The
82
+ easiest way to create one is by implementing :class: `Symfony\\ Component\\ Form\\ DataMapperInterface `
83
+ in your form type::
82
84
83
- // src/Form/DataMapper/ColorMapper .php
84
- namespace App\Form\DataMapper ;
85
+ // src/Form/ColorType .php
86
+ namespace App\Form;
85
87
86
88
use App\Painting\Color;
89
+ use Symfony\Component\Form\AbstractType;
87
90
use Symfony\Component\Form\DataMapperInterface;
88
91
use Symfony\Component\Form\Exception\UnexpectedTypeException;
89
92
use Symfony\Component\Form\FormInterface;
90
93
91
- final class ColorMapper implements DataMapperInterface
94
+ final class ColorType extends AbstractType implements DataMapperInterface
92
95
{
96
+ // ...
97
+
93
98
/**
94
99
* @param Color|null $data
95
100
*/
@@ -139,20 +144,19 @@ form fields. Recognize a familiar pattern? It's time for a data mapper::
139
144
Using the Mapper
140
145
----------------
141
146
142
- You're ready to use the data mapper for the `` ColorType `` form. Use the
143
- :method: `Symfony\\ Component\\ Form\\ FormConfigBuilderInterface::setDataMapper `
144
- method to configure the data mapper ::
147
+ After creating the data mapper, you need to configure the form to use it. This is
148
+ achieved using the :method: `Symfony\\ Component\\ Form\\ FormConfigBuilderInterface::setDataMapper `
149
+ method::
145
150
146
151
// src/Form/Type/ColorType.php
147
152
namespace App\Form\Type;
148
153
149
- use App\Form\DataMapper\ColorMapper;
150
- use Symfony\Component\Form\AbstractType;
154
+ // ...
151
155
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
152
156
use Symfony\Component\Form\FormBuilderInterface;
153
157
use Symfony\Component\OptionsResolver\OptionsResolver;
154
158
155
- final class ColorType extends AbstractType
159
+ final class ColorType extends AbstractType implements DataMapperInterface
156
160
{
157
161
public function buildForm(FormBuilderInterface $builder, array $options)
158
162
{
@@ -168,7 +172,8 @@ method to configure the data mapper::
168
172
->add('blue', IntegerType::class, [
169
173
'empty_data' => '0',
170
174
])
171
- ->setDataMapper(new ColorMapper())
175
+ // configure the data mapper for this FormType
176
+ ->setDataMapper($this)
172
177
;
173
178
}
174
179
@@ -177,19 +182,41 @@ method to configure the data mapper::
177
182
// when creating a new color, the initial data should be null
178
183
$resolver->setDefault('empty_data', null);
179
184
}
185
+
186
+ // ...
180
187
}
181
188
182
- Cool! When using the ``ColorType `` form, the custom `` ColorMapper `` will create
183
- a new ``Color `` object now.
189
+ Cool! When using the ``ColorType `` form, the custom data mapper methods will
190
+ create a new ``Color `` object now.
184
191
185
192
.. caution ::
186
193
187
194
When a form has the ``inherit_data `` option set to ``true ``, it does not use the data mapper and
188
195
lets its parent map inner values.
189
196
190
- .. tip ::
197
+ .. sidebar :: Stateful Data Mappers
198
+
199
+ Sometimes, data mappers need to access services or need to maintain their
200
+ state. In this case, you cannot implement the methods in the form type
201
+ itself. Create a separate class implementing ``DataMapperInterface `` and
202
+ initialize it in your form type::
191
203
192
- You can also implement the ``DataMapperInterface `` in the ``ColorType `` and add
193
- the ``mapDataToForms() `` and ``mapFormsToData() `` in the form type directly
194
- to avoid creating a new class. You'll then have to call
195
- ``$builder->setDataMapper($this) ``.
204
+ // src/Form/Type/ColorType.php
205
+
206
+ // ...
207
+ use App\Form\DataMapper\ColorMapper;
208
+
209
+ final class ColorType extends AbstractType
210
+ {
211
+ public function buildForm(FormBuilderInterface $builder, array $options)
212
+ {
213
+ $builder
214
+ // ...
215
+
216
+ // Initialize the data mapper class and e.g. pass some state
217
+ ->setDataMapper(new ColorMapper($options['opacity']))
218
+ ;
219
+ }
220
+
221
+ // ...
222
+ }
0 commit comments