Symfony 3 - 从传递给表单的实体对象中获取选择选项?

时间:2017-09-22 18:28:01

标签: php forms symfony entity

我有一个WorkflowType表单类,data_class属性为Workflow::class。在Controller动作函数中创建表单时,我将Workflow对象传递给states属性

public function createWorkflowAction(Request $request, Workflow $workflow) {
    $secondFormPart = $this->createForm(WorkflowType::class, $workflow);
    ...
}

在表单中添加EntityType表单字段class属性为State::class。这个实体类有多个属性,但我只使用其中一个,并希望将EntityType字段呈现为选择框:

class WorkflowType extends AbstractType {

    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options) {
        //@formatter:off
            $builder
                ->add('initialState', EntityType::class, array(
                    'class'             => State::class,
                    'choice_label'      => 'key',
                    'choice_value'      => 'key',

                    // This combination of 'expanded' and 'multiple' implements a select box
                    'expanded'          => false,
                    'multiple'          => false,
                ))...
                ...
        }
        ...
}

现在问题

  

Symfony尝试将choices initialState字段的EntityType从数据库中取出:An exception occurred while executing 'SELECT t0_.id AS id_0, t0_.key AS key_1, t0_.order AS order_2, t0_.workflow_id AS workflow_id_3 FROM testpra_State t0_'

     

但我希望从choices对象states的{​​{1}}属性中获取Workflow我传递给控制器​​中的$workflow

类似的东西:

createForm

我知道我可以使用->add('initialState', EntityType::class, array( 'class' => State::class, 'choice_label' => 'key', 'choice_value' => 'key', 'choices' => $workflow->getStates(), // This combination of 'expanded' and 'multiple' implements a select box 'expanded' => false, 'multiple' => false, )) 数组,如:

$option

但是有更简单的解决方案吗?

如果是,我怎样才能访问我在子表单中传递给$secondFormPart = $this->createForm(PraWorkflowTransitionsType::class, $workflow, array( 'states' => $workflow->getStates() )); 的对象?

2 个答案:

答案 0 :(得分:-1)

所以你必须将数组传递给表单

var arr = [{ Item: 'pen',Color: 'blue',Brand: 'cello'},{Item: 'pen',Color: 'red',Brand: 'cello'},{Item: 'pen',Color: 'blue',Brand: 'cello'}];


var uniq = arr.reduce(function(u, o1){
  delete o1.Color;
  var isExist = u.some(function(o2){
    return o2.Item === o1.Item && o2.Brand === o1.Brand;
  });
  if(!isExist)
    u.push(o1);
  return u;
},[]); 

console.log(uniq);

并将选项添加到解析器

public function createWorkflowAction(Request $request, Workflow $workflow) {
    $secondFormPart = $this->createForm(WorkflowType::class,null,array('workflow'=>$workflow));
    ... }

然后它可以通过$ options [' workflow']而不是$ workflow

来访问

答案 1 :(得分:-1)

  

但是有更简单的解决方案吗?

与评论中所述的kunicmarko20一样,该对象可通过$options['data']访问:

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

    /** @var Workflow $workflow */
    $workflow = $options['data'];
    ...
}

他还指出我应该使用ChoiceType哪个更好,因为EntityTypedesigned to load options from a Doctrine entity

  

如果是,我怎样才能访问我在子表单中传递给createForm的对象?

在我的情况下,我有一个CollectionType字段,可以动态添加entry_type TransitionType的形式。在这种情况下,您可以通过entry_options属性传递数据:

->add('transitions', CollectionType::class, array(
    'entry_type'        => TransitionType::class,
    'entry_options'     => array(
        'states'    => $workflow->getStates(),
    ),
    ...
))

并在TransitionType班级中:

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

    /** @var ArrayCollection $states */
    $states = $options['states'];
    ...
}