猿问

Symfony 4. 为什么提交的表单只是部分填充模型?

有点恐慌 - 我正在为复杂的搜索生成 Symfony 表单,即映射到实体的数据将仅用于搜索查询构建。


我从 ChoiceType 创建了简单的表单、模型和一些扩展类型,用于通过某种逻辑进行预填充选择。表单是通过 GET 方法提交的。


例如,在模型中您可以找到maker和model字段。选择 maker 后,后者使用 AJAX 填充到前端。当我提交表单maker并且model具有非默认值时,handleRequest仅填充maker模型的属性,但model保留为空。如果选中,复选框也会正确填充。总而言之,$form->getData()只返回 Maker 和复选框,其他字段为空。$request->query有所有参数。


数据映射器在这里毫无意义。而且数据中没有什么可以转换的,模型主要来自标量值。请求包含所有内容,但未正确处理。我试图实现ChoiceLoaderInterface,但这对我不起作用,因为在加载选择期间我必须有权访问options表单的 ,而我没有(我使用了这篇文章https://speakerdeck.com/heahdude/symfony -forms-use-cases-and-optimization)。


我正在使用 Symfony 4.2.4;PHP 7.2。


控制器的方法


/**

     * @Route("/search/car", name="car_search", methods={"GET"})

     * @param Request $request

     */

    public function carSearchAction(Request $request)

    {

        $carModel = new CarSimpleSearchModel();

        $form     = $this->createForm(CarSimpleSearchType::class, $carModel);

        $form->handleRequest($request);


        $form->getData();


        .....

    }

汽车简单搜索模型


class CarSimpleSearchModel

{

    public $maker;

    public $model;

    public $priceFrom;

    public $priceTo;

    public $yearFrom;

    public $yearTo;

    public $isCompanyOwner;

    public $isPrivateOwners;

    public $isRoublePrice;

}


CarSimpleSearchType 表单


class CarSimpleSearchType extends AbstractType

{

    protected $urlGenerator;


    public function __construct(UrlGeneratorInterface $urlGenerator)

    {

        $this->urlGenerator = $urlGenerator;

    }


    public function buildForm(FormBuilderInterface $builder, array $options)

    {

        $builder

            ->add('vehicle_type', HiddenType::class, [

                'data' => VehicleTypeType::CAR,

                'mapped' => false,

            ])

            ->add('maker', CarMakerSelectType::class)

            ->add('model', CarModelsSelectType::class)

            ->add(

                'priceFrom',

                VehiclePriceRangeType::class,

                [

                    'vehicle_type' => VehicleTypeType::CAR,

                ]

            )


慕的地8271018
浏览 131回答 1
1回答

慕丝7291255

就我而言,我有一个EntityType由最初禁用的 ajax 填充的依赖项。从choiceswhere 开始null,它InvalidValueException在提交时返回一个。我必须做的是创建一个EventListener并添加choices当前“主要”字段的有效值。基本上就是这样,或多或少适合您的情况。原始形式:// Setup Fields$builder    ->add('maker', CarMakerSelectType::class)    ->add('model', CarModelsSelectType::class, [            'choices' => [],            // I was setting the disabled on a Event::PRE_SET_DATA if previous field was null            // since I could be loading values from the database but I guess you can do it here            'attr' => ['disabled' => 'disabled'],        ]    );$builder->addEventSubscriber(new ModelListener($this->extractor));添加回有效选择的事件订阅者:class ModelListener implements EventSubscriberInterface{    public function __construct(VehicleExtractorService $extractor)    {        $this->extractor = $extractor;    }    public static function getSubscribedEvents()    {        return [            FormEvents::PRE_SUBMIT => 'onPreSubmitData',        ];    }    public function onPreSubmitData(FormEvent $event)    {        // At this point you get only the scalar values, Model hasn't been transformed yet        $data = $event->getData();        $form = $event->getForm();        $maker_id = $data['maker'];            $model= $form->get('model');            $options = $model->getConfig()->getOptions();            if (!empty($maker_id)) {                unset($options['attr']['disabled']);                $options['choices'] = $this->extractor->getModelsFor($maker_id);                $form->remove('model');                $form->add('model', CarModelsSelectType::class, $options );            }        }    }}
随时随地看视频慕课网APP
我要回答