symfony:从窗体访问控制器变量


symfony: access controller variables from form

从Symfony开始是一条学习曲线。即使在阅读了几个小时之后,我也无法理解这个可能很简单的问题。我想用实体中的值加载一个选择表单。

控制器:

namespace AppBundle'Controller
class ItemController extends Controller
{ 
  public function itemAction (Request $request)
    {
      $myItems = new Itemlist();
      //some statements to fill $myItems
      $form = $this->createForm (AllitemsType::class, $myItems);
      // some more stuff
      return $this->render (...);
    }
}

实体:

namespace AppBundle'Entity;
class Itemlist 
{
  protected $choices;
  protected $defaultvalue;
  public function __construct ()
  {
    $choices = array();
  }
  // all the get and set-methods to fill/read the $choices array and $defaultvalue
}

形式:

namespace AppBundle'Form
class AllitemsType extends AbstractType
{
  public function buildForm (FormBuilderInterface $builder, array $options)
  {
    // and here is my problem: how can I fill next two lines with values from the Itemlist-Entity?
    // The Itemlist instance has been build in the controller and is unknown here
    $items = ??? // should be 'AppBundle'Entity'Itemlist->$choices
    $defaultitem = ??? // should be 'AppBundle'Entity'Itemlist->$defaultvalue
    $choices_of_items = array (
      'choices' => $items,
      'expanded' => true,
      'multiple' => false,
      'data' => $defaultitem,
    );
    $builder->add ('radio1', ChoiceType::class, $choices_of_items);
  }
}

感谢任何帮助,Wolfram

$builder->add('choices', ChoiceType::class);

当您将实体绑定到表单时,获取值并将其设置回表单的过程应该是自动的。当然,您需要为AllitemsType 中的choices字段设置setter和getter

要给出一个完整的答案——上面的部分就是所谓的"最佳实践之一"——你也可以选择以下之一

$items = $options['data'];

$builder->addEventListener(
  FormEvents::PRE_SET_DATA, function (FormEvent $event) {
    $allItems = $event->getData();
    $form = $event->getForm();
    $form->add('radio1', ChoiceType::class, [
      'choices' => $allItems
    ]);
});

第二个应该是首选,因为在options['data']中,实体可能在表单事件的生存期内发生更改。

使用createForm对象传递变量。

控制器:

    namespace AppBundle'Controller
    class ItemController extends Controller
    { 
      public function itemAction (Request $request)
        {
          $myItems = new Itemlist();
          $formVars = array("items" => array(1,2,3,4,6), "defaultItems" => 2); // Store variables
          ^^
          //some statements to fill $myItems
          $form = $this->createForm (new AllitemsType($formVars), $myItems);
                                                      ^^
          // some more stuff
          return $this->render (...);
        }
    }

现在在表单中创建构造函数,并在form中设置类变量itemsdefaultitem

形式:

namespace AppBundle'Form
class AllitemsType extends AbstractType
{
  $this->items = array();
  $this->defaultitem = 0;
  public function __construct($itemArr)
  {
    $this->items = $itemArr['items'];
    $this->defaultitem = $itemArr['defaultItems'];
  }
  public function buildForm (FormBuilderInterface $builder, array $options)
  {
    $choices_of_items = array (
      'choices' => $this->items, // User class variable
      'expanded' => true,
      'multiple' => false,
      'data' => $this->defaultitem, // User class variable
    );
    $builder->add ('radio1', ChoiceType::class, $choices_of_items);
  }
}

它应该能解决你的问题。