Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Form Norm Data vs. View Data - 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 (e.g. 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's not commonly used directly.
    View Data - This is the format that's used to fill in the form fields themselves. It's 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 don't understand the difference between norm data and view data. What is the use case for norm data? The next paragraph from the documentation "So why Use the Model Transformer?" does not make any sense to me.

like image 244
Isinlor Avatar asked Dec 13 '16 07:12

Isinlor


2 Answers

The best explanation I have found is in the Symfony's 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's 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 "Y-m-d" 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's extend our above date field to store the value
 * either as "Y-m-d" 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 <[email protected]>
 * @author Bernhard Schussek <[email protected]>
 */
class Form implements \IteratorAggregate, FormInterface
{
    ...
}

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


So, basically, every form has a data in three different formats. The first two are: the model data - the data you use in a domain model, and the view data - the data you typically output as a string in HTML or you enter in the form fields before submitting.

Two simple examples would be a TextType and a NumberType. In the TextType, the model data is the string, and the view data is the string.

In the NumberType, the model data is a float - in your application you are handling float type, and the view data is the localized string.

But, on the other side, if we take a look at a DateType, things are a little bit complicated, because the model data could be string ('YYYY-MM-DD'), an integer (unix timestamp), an array or DateTime object. The view data could be localized string or the array.

enter image description here

For example, if you want to write an event listener, you can't be sure what data format would you get:

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, Sf form has a third data format - normalized format. That format is static - you always know what you'll 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();
 }
like image 71
Matko Đipalo Avatar answered Oct 03 '22 06:10

Matko Đipalo


Let's take a DateTimeType widget as example.

The model Data is a Datetime

The norm data is an array (in the documentation)

The view data is a string (an input text for example)

like image 27
goto Avatar answered Oct 03 '22 04:10

goto