@@ -78,18 +78,23 @@ one of the values is changed.
7878
7979The red, green and blue form fields have to be mapped to the constructor
8080arguments 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::
8284
83- // src/Form/DataMapper/ColorMapper .php
84- namespace App\Form\DataMapper ;
85+ // src/Form/ColorType .php
86+ namespace App\Form;
8587
8688 use App\Painting\Color;
89+ use Symfony\Component\Form\AbstractType;
8790 use Symfony\Component\Form\DataMapperInterface;
8891 use Symfony\Component\Form\Exception\UnexpectedTypeException;
8992 use Symfony\Component\Form\FormInterface;
9093
91- final class ColorMapper implements DataMapperInterface
94+ final class ColorType extends AbstractType implements DataMapperInterface
9295 {
96+ // ...
97+
9398 /**
9499 * @param Color|null $data
95100 */
@@ -139,20 +144,19 @@ form fields. Recognize a familiar pattern? It's time for a data mapper::
139144Using the Mapper
140145----------------
141146
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::
145150
146151 // src/Form/Type/ColorType.php
147152 namespace App\Form\Type;
148153
149- use App\Form\DataMapper\ColorMapper;
150- use Symfony\Component\Form\AbstractType;
154+ // ...
151155 use Symfony\Component\Form\Extension\Core\Type\IntegerType;
152156 use Symfony\Component\Form\FormBuilderInterface;
153157 use Symfony\Component\OptionsResolver\OptionsResolver;
154158
155- final class ColorType extends AbstractType
159+ final class ColorType extends AbstractType implements DataMapperInterface
156160 {
157161 public function buildForm(FormBuilderInterface $builder, array $options)
158162 {
@@ -168,7 +172,8 @@ method to configure the data mapper::
168172 ->add('blue', IntegerType::class, [
169173 'empty_data' => '0',
170174 ])
171- ->setDataMapper(new ColorMapper())
175+ // configure the data mapper for this FormType
176+ ->setDataMapper($this)
172177 ;
173178 }
174179
@@ -177,19 +182,41 @@ method to configure the data mapper::
177182 // when creating a new color, the initial data should be null
178183 $resolver->setDefault('empty_data', null);
179184 }
185+
186+ // ...
180187 }
181188
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.
184191
185192.. caution ::
186193
187194 When a form has the ``inherit_data `` option set to ``true ``, it does not use the data mapper and
188195 lets its parent map inner values.
189196
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::
191203
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