Forms 如何在Symfony表单中的ChoiceType中标识“选定”值

Forms 如何在Symfony表单中的ChoiceType中标识“选定”值,forms,symfony,Forms,Symfony,我正在尝试创建一个页面,用户可以在其中在数据库中创建一批新的发票记录。每个成员都在实体中分配了“默认金额”和“默认货币”属性。对于默认货币,它以E(欧元)或D(美元)的形式存储在数据库中 但是,在创建新发票的页面中,每个成员的“默认金额”都已正确填充,但货币选择框仅显示“欧元”,即使该成员具有Defaultinvoicecurrency=D。这是因为selected从未被添加到为成员存储在数据库中的任何select选项中 如果使用从下拉列表中选择的货币提交表单,则这些货币将正确添加到数据库中(

我正在尝试创建一个页面,用户可以在其中在数据库中创建一批新的发票记录。每个成员都在实体中分配了“默认金额”和“默认货币”属性。对于默认货币,它以
E
(欧元)或
D
(美元)的形式存储在数据库中

但是,在创建新发票的页面中,每个成员的“默认金额”都已正确填充,但货币选择框仅显示“欧元”,即使该成员具有Defaultinvoicecurrency=
D
。这是因为
selected
从未被添加到为成员存储在数据库中的任何select选项中

如果使用从下拉列表中选择的货币提交表单,则这些货币将正确添加到数据库中(
E
D

成员实体:

/**
 * @var integer
 * @ORM\COLUMN(type="decimal", precision=7, scale=2)
 * @Assert\NotBlank
 * @Assert\Regex(
 *     pattern="/^\s*-?[1-9]\d*(\.\d{1,2})?\s*$/",
 *     match=true,
 *     message="Please check - amount should have up to two decimal places")
 */
protected $defaultinvoiceamount;

/** eg E=EUR or D=USD
 * @var string
 * @ORM\COLUMN(type="string", length=1)
 */
protected $defaultinvoicecurrency;
class Invoice
{
    /**
     * @ORM\ManyToOne(targetEntity="InvoiceBatch", inversedBy="invoice_ids")
     * @ORM\JoinColumn(name="invoicebatch_id", referencedColumnName="id")
     */
    protected $invoicebatch_id;

    /**
     * @ORM\ManyToOne(targetEntity="Member", inversedBy="invoice_ids",cascade={"persist"})
     * @ORM\JoinColumn(name="member_id",     referencedColumnName="id")
     */
    protected $member_id;

    /*
     * @var integer
     * @ORM\COLUMN(type="decimal", precision=7, scale=2)
     * @Assert\NotBlank
     * @Assert\Regex(
     *     pattern="/^\s*-?[1-9]\d*(\.\d{1,2})?\s*$/",
     *     match=true,
     *     message="Please check - amount should have up to two decimal places")
     */
    protected $amount;

    /**  eg PEN or USD
     * @var string
     * @ORM\COLUMN(type="string", length=1)
     */
    protected $currency;
public function newInvoiceAction(Request $request)
{
    $em = $this->getDoctrine()->getManager();
    $members = $em->getRepository('AppBundle:Member')->findActiveMembers();

    $batch = new InvoiceBatch();
    foreach($members as $member) {
        $invoice=new Invoice();
        $invoice->setMemberId($member);
        $invoice->setAmount(   $member->getDefaultinvoiceamount()   );
        $invoice->setCurrency( $member->getDefaultinvoicecurrency() );
        $invoice->setinvoicebatchid($batch);
        $batch->addInvoiceId($invoice);
    }

    $form=$this->createForm(InvoiceType::class, $invoice);
    $form->handleRequest($request);
    if ($form->isSubmitted() && ($form->isValid())) {
    /* ... */
}
class InvoiceType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('amount', MoneyType::class, array(
                'label' => 'Amount',
            ))

            ->add('currency',ChoiceType::class, array(
                'data'=> 'Defaultinvoicecurrency',
                'choices' => array('Euro' => 'E', 'US Dollar' => 'D'),
                'choices_as_values' => true,
            ))
    /* ... */
    }
}
发票实体:

/**
 * @var integer
 * @ORM\COLUMN(type="decimal", precision=7, scale=2)
 * @Assert\NotBlank
 * @Assert\Regex(
 *     pattern="/^\s*-?[1-9]\d*(\.\d{1,2})?\s*$/",
 *     match=true,
 *     message="Please check - amount should have up to two decimal places")
 */
protected $defaultinvoiceamount;

/** eg E=EUR or D=USD
 * @var string
 * @ORM\COLUMN(type="string", length=1)
 */
protected $defaultinvoicecurrency;
class Invoice
{
    /**
     * @ORM\ManyToOne(targetEntity="InvoiceBatch", inversedBy="invoice_ids")
     * @ORM\JoinColumn(name="invoicebatch_id", referencedColumnName="id")
     */
    protected $invoicebatch_id;

    /**
     * @ORM\ManyToOne(targetEntity="Member", inversedBy="invoice_ids",cascade={"persist"})
     * @ORM\JoinColumn(name="member_id",     referencedColumnName="id")
     */
    protected $member_id;

    /*
     * @var integer
     * @ORM\COLUMN(type="decimal", precision=7, scale=2)
     * @Assert\NotBlank
     * @Assert\Regex(
     *     pattern="/^\s*-?[1-9]\d*(\.\d{1,2})?\s*$/",
     *     match=true,
     *     message="Please check - amount should have up to two decimal places")
     */
    protected $amount;

    /**  eg PEN or USD
     * @var string
     * @ORM\COLUMN(type="string", length=1)
     */
    protected $currency;
public function newInvoiceAction(Request $request)
{
    $em = $this->getDoctrine()->getManager();
    $members = $em->getRepository('AppBundle:Member')->findActiveMembers();

    $batch = new InvoiceBatch();
    foreach($members as $member) {
        $invoice=new Invoice();
        $invoice->setMemberId($member);
        $invoice->setAmount(   $member->getDefaultinvoiceamount()   );
        $invoice->setCurrency( $member->getDefaultinvoicecurrency() );
        $invoice->setinvoicebatchid($batch);
        $batch->addInvoiceId($invoice);
    }

    $form=$this->createForm(InvoiceType::class, $invoice);
    $form->handleRequest($request);
    if ($form->isSubmitted() && ($form->isValid())) {
    /* ... */
}
class InvoiceType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('amount', MoneyType::class, array(
                'label' => 'Amount',
            ))

            ->add('currency',ChoiceType::class, array(
                'data'=> 'Defaultinvoicecurrency',
                'choices' => array('Euro' => 'E', 'US Dollar' => 'D'),
                'choices_as_values' => true,
            ))
    /* ... */
    }
}
控制器:

/**
 * @var integer
 * @ORM\COLUMN(type="decimal", precision=7, scale=2)
 * @Assert\NotBlank
 * @Assert\Regex(
 *     pattern="/^\s*-?[1-9]\d*(\.\d{1,2})?\s*$/",
 *     match=true,
 *     message="Please check - amount should have up to two decimal places")
 */
protected $defaultinvoiceamount;

/** eg E=EUR or D=USD
 * @var string
 * @ORM\COLUMN(type="string", length=1)
 */
protected $defaultinvoicecurrency;
class Invoice
{
    /**
     * @ORM\ManyToOne(targetEntity="InvoiceBatch", inversedBy="invoice_ids")
     * @ORM\JoinColumn(name="invoicebatch_id", referencedColumnName="id")
     */
    protected $invoicebatch_id;

    /**
     * @ORM\ManyToOne(targetEntity="Member", inversedBy="invoice_ids",cascade={"persist"})
     * @ORM\JoinColumn(name="member_id",     referencedColumnName="id")
     */
    protected $member_id;

    /*
     * @var integer
     * @ORM\COLUMN(type="decimal", precision=7, scale=2)
     * @Assert\NotBlank
     * @Assert\Regex(
     *     pattern="/^\s*-?[1-9]\d*(\.\d{1,2})?\s*$/",
     *     match=true,
     *     message="Please check - amount should have up to two decimal places")
     */
    protected $amount;

    /**  eg PEN or USD
     * @var string
     * @ORM\COLUMN(type="string", length=1)
     */
    protected $currency;
public function newInvoiceAction(Request $request)
{
    $em = $this->getDoctrine()->getManager();
    $members = $em->getRepository('AppBundle:Member')->findActiveMembers();

    $batch = new InvoiceBatch();
    foreach($members as $member) {
        $invoice=new Invoice();
        $invoice->setMemberId($member);
        $invoice->setAmount(   $member->getDefaultinvoiceamount()   );
        $invoice->setCurrency( $member->getDefaultinvoicecurrency() );
        $invoice->setinvoicebatchid($batch);
        $batch->addInvoiceId($invoice);
    }

    $form=$this->createForm(InvoiceType::class, $invoice);
    $form->handleRequest($request);
    if ($form->isSubmitted() && ($form->isValid())) {
    /* ... */
}
class InvoiceType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('amount', MoneyType::class, array(
                'label' => 'Amount',
            ))

            ->add('currency',ChoiceType::class, array(
                'data'=> 'Defaultinvoicecurrency',
                'choices' => array('Euro' => 'E', 'US Dollar' => 'D'),
                'choices_as_values' => true,
            ))
    /* ... */
    }
}
表单类型:

/**
 * @var integer
 * @ORM\COLUMN(type="decimal", precision=7, scale=2)
 * @Assert\NotBlank
 * @Assert\Regex(
 *     pattern="/^\s*-?[1-9]\d*(\.\d{1,2})?\s*$/",
 *     match=true,
 *     message="Please check - amount should have up to two decimal places")
 */
protected $defaultinvoiceamount;

/** eg E=EUR or D=USD
 * @var string
 * @ORM\COLUMN(type="string", length=1)
 */
protected $defaultinvoicecurrency;
class Invoice
{
    /**
     * @ORM\ManyToOne(targetEntity="InvoiceBatch", inversedBy="invoice_ids")
     * @ORM\JoinColumn(name="invoicebatch_id", referencedColumnName="id")
     */
    protected $invoicebatch_id;

    /**
     * @ORM\ManyToOne(targetEntity="Member", inversedBy="invoice_ids",cascade={"persist"})
     * @ORM\JoinColumn(name="member_id",     referencedColumnName="id")
     */
    protected $member_id;

    /*
     * @var integer
     * @ORM\COLUMN(type="decimal", precision=7, scale=2)
     * @Assert\NotBlank
     * @Assert\Regex(
     *     pattern="/^\s*-?[1-9]\d*(\.\d{1,2})?\s*$/",
     *     match=true,
     *     message="Please check - amount should have up to two decimal places")
     */
    protected $amount;

    /**  eg PEN or USD
     * @var string
     * @ORM\COLUMN(type="string", length=1)
     */
    protected $currency;
public function newInvoiceAction(Request $request)
{
    $em = $this->getDoctrine()->getManager();
    $members = $em->getRepository('AppBundle:Member')->findActiveMembers();

    $batch = new InvoiceBatch();
    foreach($members as $member) {
        $invoice=new Invoice();
        $invoice->setMemberId($member);
        $invoice->setAmount(   $member->getDefaultinvoiceamount()   );
        $invoice->setCurrency( $member->getDefaultinvoicecurrency() );
        $invoice->setinvoicebatchid($batch);
        $batch->addInvoiceId($invoice);
    }

    $form=$this->createForm(InvoiceType::class, $invoice);
    $form->handleRequest($request);
    if ($form->isSubmitted() && ($form->isValid())) {
    /* ... */
}
class InvoiceType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('amount', MoneyType::class, array(
                'label' => 'Amount',
            ))

            ->add('currency',ChoiceType::class, array(
                'data'=> 'Defaultinvoicecurrency',
                'choices' => array('Euro' => 'E', 'US Dollar' => 'D'),
                'choices_as_values' => true,
            ))
    /* ... */
    }
}

将发票实体实例传递给表单时,正确的实体数据字段为“货币”。即,您需要从该表单字段中删除多余的“数据”定义:

->add('currency',ChoiceType::class, array(
    'choices' => array('Euro' => 'E', 'US Dollar' => 'D'),
    'choices_as_values' => true,
))

是否尝试删除表单类中的“数据”=>“Defaultinvoicecurrency”设置?我不确定代码中该定义的目标是什么,但由于您似乎正在传递表单的发票实体实例,您可能应该只使用“货币”字段…@ejuhjav…非常感谢!除了排除
数据=>
之外,我几乎什么都试过了(!)。请随意发布一个不需要数据的答案