Form Norm Data vs. Data View - What's the Difference?

The documentation says:

In any form, the three different types of data are: Model data - This is the data in the format used in your application (eg an Issue object). If you call Form::getData() or Form::setData(), you're dealing with the "model" data. Norm Data - This is a normalized version of your data and is commonly the same as your "model" data (though not in our example). It not commonly used directly. View Data - This is the format that used to fill in the form fields themselves. It also the format in which the user will submit the data. When you call Form::submit($data), the $data is in the "view" data format. 

But I do not understand the difference between norm data and data. What is the precedent of regulatory data? The next paragraph is from the documentation "So why use a model transformer?" doesn't make any sense to me.

+6
source share
4 answers

The best explanation I found is in the Symfony Form class description:

 <?php ... namespace Symfony\Component\Form; use ... /** * Form represents a form. * * To implement your own form fields, you need to have a thorough understanding * of the data flow within a form. A form stores its data in three different * representations: * * (1) the "model" format required by the form object * (2) the "normalized" format for internal processing * (3) the "view" format used for display * * A date field, for example, may store a date as "Ymd" string (1) in the * object. To facilitate processing in the field, this value is normalized * to a DateTime object (2). In the HTML representation of your form, a * localized string (3) is presented to and modified by the user. * * In most cases, format (1) and format (2) will be the same. For example, * a checkbox field uses a Boolean value for both internal processing and * storage in the object. In these cases you simply need to set a value * transformer to convert between formats (2) and (3). You can do this by * calling addViewTransformer(). * * In some cases though it makes sense to make format (1) configurable. To * demonstrate this, let extend our above date field to store the value * either as "Ymd" string or as timestamp. Internally we still want to * use a DateTime object for processing. To convert the data from string/integer * to DateTime you can set a normalization transformer by calling * addNormTransformer(). The normalized data is then converted to the displayed * data as described before. * * The conversions (1) -> (2) -> (3) use the transform methods of the transformers. * The conversions (3) -> (2) -> (1) use the reverseTransform methods of the transformers. * * @author Fabien Potencier < fabien@symfony.com > * @author Bernhard Schussek < bschussek@gmail.com > */ class Form implements \IteratorAggregate, FormInterface { ... } 

EDIT: Here is a video from the author of the component of the form Sf (co), where he explains the data formats and gives an example of using the normalized format β†’ https://youtu.be/Q80b9XeLUEA?t=7m6s


So basically, each form has data in three different formats. The first two: model data is the data that you use in the domain model, and view data is data that is usually displayed as a string in HTML, or you enter it in the form fields before sending.

Two simple examples: TextType and NumberType. In TextType, model data is a string, and view data is a string.

In the NumberType type, the model data is a float β€” in your application, you process the float type, and the view data is a localized string.

But on the other hand, if we look at DateType, things will be a little more complicated, because the model data can be string ("YYYY-MM-DD"), an integer (unix timestamp) array, or a DateTime object. View data can be a localized string or array.

enter image description here

For example, if you want to write an event listener, you cannot be sure which data format you will receive:

 class MyDateType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add... ->addEventListener( FormEvents::FormEvents::SUBMIT, array($this, 'onSubmit') ) ; } public function onSubmit(FormEvent $event) { // BUT WHAT FORMAT DO I GET??? $data = $event->getForm()->getData(); } } 

Fortunately, the Sf form has a third data format - the normalized format. This format is static - you always know what you get, it is always the same data type!

enter image description here

  public function onSubmit(FormEvent $event) { // $data will be DateTime object! $data = $event->getForm()->getNormData(); } 
+8
source

A brief explanation / simplification that I used to remember such things when I started learning symfony forms:

  • Model data: data in the model / object / in any form. This is your data source data format.
  • Normal data : data in the form of a form field. If you have CollectionType , for example, you have an array, if you have DateTimeType , you have DateTime , etc.
  • View data : data in the view form.

Basically, if your formats are β€œmatched” between these β€œlayers”, you never need to (*) create a transformer.

Just for an example of each type:

Model β†’ Norma

If you have an entity ( model data ) and you have an EntityType field in your form ( normal data ), you do not need to use any transformer

If you have an entity ( model data ) and you have a TextType field to represent your entity, you need to use ModelTransformer , since your formats are not congruent

Norma β†’ View

(*) Any DateType or DateTimeType has a transformer inserted directly into the data type: it is used to convert from formatting the date (user) (time zone) and formatting the normative (or model) (time zone)

As you can see here, the conversion takes place not only between incongruent data types, but also within the same type.

You can also check out this presentation.

+1
source

Take the DateTimeType widget as an example.

Model data are Datetime

These norms are an array ( in the documentation )

Presentation data is a string (for example, input text)

0
source

In addition to other answers.

Symfony has a very strange case where ViewData become a ModelData model and vice versa.

It depends on whether the form is compilation or not.

Cm:

line 634 send to ViewTransformer a combination of view data (from the main form) and model data (from children's forms). Was this really expected?

Yes, that is :) for the reasons I explained above.

To renew:

Simple form => view data == request data

Compound form => view data == (data_class | array) displaying model model data using DataMapper.

Source: https://github.com/symfony/symfony/issues/22371#issuecomment-293494324

and

The internally composite form uses data of its kind to compare the data of children.

I did a bit more research:

As you say, the composite option determines whether PropertyPathMapper will be used. This is normal. ->setDataMapper($options['compound'] ? new PropertyPathMapper($this->propertyAccessor) : null)

Also, as you say, the Form class uses mapper to map view data to forms. This is also OK. $this->config->getDataMapper()->mapDataToForms($viewData, $iterator);

Then the PropertyPathMapper mapper sets up the form data. Hmm ... $form->setData($this->propertyAccessor->getValue($data, $propertyPath));

Why does the PropertyPathMapper trough Form set the ViewData for forms that expect ModelData? public function setData($modelData);

How has ViewData changed to ModelData in mapper? Why are ModelData not showing up as forms? Why is data_class applicable to ViewData and not ModelData, where does that make sense?

Source: https://github.com/symfony/symfony/issues/20880#issuecomment-267129575

0
source

Source: https://habr.com/ru/post/1013120/


All Articles