【问题标题】:Symfony 3 form + AureliaSymfony 3 形式 + Aurelia
【发布时间】:2016-09-07 14:12:15
【问题描述】:

所以我在 Symfony 3 中构建了一个 web 应用程序,使用表单类型并在页面上呈现表单。我开始使用 Aurelia,并尝试通过 Aurelia 自定义元素在页面上呈现 Symfony 表单,然后将表单发布回 symfony。我已经到了在提交时验证表单的地步,但它从未验证过。有人可以看看下面的代码,看看我是否在某处遗漏了什么吗?

表格类型:

<?php

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use AppBundle\Service\PayeeService;

class PayeeType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', TextType::class)
            ->add('category', ChoiceType::class, [
                'choices' => [
                    'Uncategorized' => PayeeService::CATEGORY_UNCATEGORIZED,
                    'Installment Loan' => PayeeService::CATEGORY_INSTALLMENT_LOAN,
                    'Credit Card' => PayeeService::CATEGORY_CREDIT_CARD,
                    'Utility' => PayeeService::CATEGORY_UTILITY,
                    'Mortgage' => PayeeService::CATEGORY_MORTGAGE,
                    'Entertainment' => PayeeService::CATEGORY_ENTERTAINMENT
                ],
                'choices_as_values' => true
                ])
            ->add('amount', MoneyType::class, ['currency' => 'USD', 'grouping' => true])
            ->add('frequency', ChoiceType::class, [
                'choices' => [
                    'Recurring' => PayeeService::FREQUENCY_RECURRING,
                    'One-time' => PayeeService::FREQUENCY_ONETIME
                ],
                'choices_as_values' => true
                ])
            ->add('method', ChoiceType::class, [
                'choices' => [
                    'ACH' => PayeeService::PAY_METHOD_ACH,
                    'Check' => PayeeService::PAY_METHOD_CHECK
                ],
                'choices_as_values' => true
                ])
            ->add('dateLastPaid', DateType::class)
            ->add('dueDate', DateType::class)
            ->add('gracePeriod', IntegerType::class)
            ->add('balance', MoneyType::class, ['currency' => 'USD', 'grouping' => true])
            ->add('active', CheckboxType::class, ['label' => 'Active', 'data' => true])
            ->add('save', SubmitType::class, ['label' => 'Save Payee'])
        ;
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\Payee'
        ));
    }
}

控制器:

<?php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;

class FormController extends Controller
{
    /**
     * @Route("/_form/entity/{entity}", name="new_entity_form")
     * @Method("GET")
     */
    public function getFormForNewEntity(Request $request)
    {
        $rawName = $request->get('entity');
        $content = $request->getContent();
        $data = json_decode($content, true);
        $formName = strtolower($rawName) . "_form";
        $submitFunction = $data['submitFunction'];
        $entityName = "AppBundle\Entity\\" . $rawName;
        $entity = new $entityName();
        $form = $this->createForm("\AppBundle\Form\\{$rawName}Type", $entity);
        return $this->render('form/form.html.twig', [
            'name' => $formName,
            'form' => $form->createView(),
            'submitFunction' => $submitFunction]);
    }

    /**
     * @Route("/_form/entity/{entity}", name="new_entity_create")
     * @Method("POST")
     */
    public function saveFormForNewEntity(Request $request)
    {
        $em = $this->getDoctrine()->getManager();
        $rawName = $request->get('entity');
        $entityName = "AppBundle\Entity\\" . $rawName;
        $entity = new $entityName();
        $form = $this->createForm("\AppBundle\Form\\{$rawName}Type", $entity);
        $form->handleRequest($request);
        if ($form->isValid()) {
            $em->persist($entity);
            $em->flush();
            return new JsonResponse(['result' => true]);
        } elseif ($form->isEmpty()) {
            return new JsonResponse(['result' => false, 'errors' => 'form empty']);
        } else {
            return new JsonResponse(['result' => false, 'errors' => iterator_to_array($form->getErrors(true))]);
        }
    }
}

表格树枝:

{{ form_start(form, {'attr': {'id':name, 'role':'form', 'submit.delegate':submitFunction}}) }}
{{ form_widget(form) }}
{{ form_end(form) }}

Aurelia 组件js:

import {InlineViewStrategy} from 'aurelia-framework';
import {customElement, bindable, inject} from 'aurelia-framework';
import $ from 'jquery';
import {HttpClient} from 'aurelia-http-client';
import 'fetch';

@customElement('symfony-form')
@inject(Element)
export class SymfonyForm {

    @bindable entity;

    constructor(element) {
        this.content = '';
        this.http = new HttpClient();
        this.http.configure(config => {
          config
            .withBaseUrl('http://localhost:8000/');
        });


        this.element = element;
    }

    bind(binding, override) {
        return this.http.get('_form/entity/' + this.entity, {'submitFunction': 'submit()'})
        //.then(response => response.html())
        .then(response => {
            this.content = response.response;
        });
    }

    submit() {
        // application/x-www-form-urlencoded
        this.http.createRequest('_form/entity/' + this.entity)
            .withHeader('Content-Type', 'application/x-www-form-urlencoded')
            .asPost()
            .withContent($(this.element).find('form').serialize())
            .send()
            .then(response => {
                alert(response.response);
            });
        //alert('submitted ' + this.entity);
        // return this.http.post('_form/entity/' + this.entity, $(this.element).find('form').serialize())
        // .then(response => {
        //     alert(response.response);
        // });
    }
}

aurelia 组件视图:

<template>
    <form role="form" submit.delegate="submit()">
        <div innerHTML.bind="content"></div>
    </form>
</template>

aurelia 页面:

<template>
    <require from="form"></require>
  <section class="au-animate">
    <h2>${heading}</h2>
    <form role="form" submit.delegate="submit()">
      <div class="form-group">
        <label for="fn">First Name</label>
        <input type="text" value.bind="firstName" class="form-control" id="fn" placeholder="first name">
      </div>
      <div class="form-group">
        <label for="ln">Last Name</label>
        <input type="text" value.bind="lastName" class="form-control" id="ln" placeholder="last name">
      </div>
      <div class="form-group">
        <label>Full Name</label>
        <p class="help-block">${fullName | upper}</p>
      </div>
      <button type="submit" class="btn btn-default">Submit</button>
    </form>
    <symfony-form entity="Payee"></symfony-form>
  </section>
</template>

【问题讨论】:

  • 为什么不想在 Aurelia 上拥有一个单页应用程序作为前端,而只使用 Symfony 作为后端的 API?
  • 我也在想同样的事情。另外我不确定你问的是symfony还是js中的表单验证?
  • @AlexanderM。我打算为前端做一个 SPA,但我希望使用我现有的 symfony 表单来免费获得一些验证和 CRUD 操作。
  • @tftd 我在询问 symfony 中的验证。 $form->isValid() 总是返回 false,而 $form->getErrors() 调用什么也不返回。
  • 我明白了。那么这里的问题是您正在使用 Aurelia 来呈现表单模板。如果您阅读文档here,您会发现您需要使用{{ form_start(form) }}{{ form_end(form) }},其中包括一些隐藏的CSFR 字段。您可以使用{{ form_widget(form._token) }} 显式呈现CSFR 字段。我想这就是让您的表单无法通过验证的原因。

标签: aurelia symfony


【解决方案1】:

我不是 SPA 或 JS 框架方面的专家,但据我所知,问题是缺少具有正确标记的 CSFR 字段,而且我不相信您的输入被正确命名为 symphony正确阅读它们(我可能错过了处理的地方,如果是这样,我深表歉意)。您需要将输入名称格式化如下:

<input type="text" name="formname[formfield]" />

因此,例如,我认为您需要您的姓名字段为:

<input type="text" name="payeetype[name]" />

【讨论】:

    猜你喜欢
    • 2018-03-13
    • 1970-01-01
    • 1970-01-01
    • 2017-10-18
    • 1970-01-01
    • 2022-08-04
    • 1970-01-01
    • 2016-02-28
    • 1970-01-01
    相关资源
    最近更新 更多