【问题标题】:Symfony Form incompatible with AngularJS $resourceSymfony 表单与 AngularJS $resource 不兼容
【发布时间】:2014-09-01 09:02:00
【问题描述】:

我有一个由 RESTful Symfony 应用程序支持的 AngularJS 应用程序。我对 POST 用户有疑问(例如 POST /api/users/123)。

这是 Symfony 表单在 POST 请求(编辑或提交资源)中所期望的:

{
  "user": {
    "email":"foo@mnapoli.fr"
  }
}

您在这里看到被发布的对象被包装在另一个user: {…} 对象(代表表单)中。

这是 Angular 的 $resource 在调用 user.$save() 时将发布的内容:

{
  "email":"foo@mnapoli.fr"
}

这里没有包装。对象直接发布。

  • 哪一个是“正确的”,即 RESTful?
  • 如何让 Symfony 或 Angular 与另一个一起工作(基于之前的答案)?

【问题讨论】:

    标签: forms angularjs rest symfony post


    【解决方案1】:

    以安静的方式创建资源的有效 POST 请求没有 ID。根据定义,您可以 PUT 到一个 id。如果目标存在,则对其进行编辑,否则将创建。关于您的第一个问题,第二种形式会更“正确”。

    基本上你定义了表单类型,所以这完全取决于你(没有“它期望”)。一个例子可以是

    class UserType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('email')
            ;
        }
    
        public function getName()
        {
            return 'user_form';
        }
    }
    

    然后在你的控制器中传递一个空的用户实体

    public function newAction()
    {
        $user = ...;
        $form = $this->createForm(new UserType(), $user);
    
        // ...
    }
    

    请参阅official book chapter 了解更多关于 SF2 的表格。

    【讨论】:

    • 嗨,我想我们说的不是同一件事。两种格式之间的区别不在于 id,而是 Symfony 期望对象被包裹在另一个代表表单的对象中(即user: {…}),而 Angular 将直接发布对象本身,而不包裹它。我已经更新了我的问题。
    • 现在我明白你的意思了,你的表单类型的名称有问题,它通常会添加到输入字段名称之前。
    • 是的,就是这样!
    【解决方案2】:

    这是我设法解决它的方法,但如果它存在,我渴望更清洁的解决方案。

    原来表单类型的名字可以为空:

    class UserType extends AbstractType
    {
        // ..
    
        public function getName()
        {
            return '';
        }
    }
    

    这使得这是一个有效的提交:

    {
      "email":"foo@mnapoli.fr"
    }
    

    【讨论】:

    • 我认为这是一个完全有效的解决方案。甚至@BernhardSchussek 也推荐了它(尽管for some other problem)。
    • 感谢链接@nietonfir 它也证实了我在代码中读到的内容(它似乎是一个有效的用例)。我现在会接受这个答案(当 SO 允许时),如果出现更好的选择,请切换。
    • 我深入研究代码并得出相同的解决方案,但认为应该有更好的方法来做到这一点。你有没有更好的解决方案?
    • @vishal nope,显然这就是它的本意……
    【解决方案3】:

    据我所知,您可以只提交特定的表单数据,而不是提交整个数组,并将表单名称作为键......

    $form->submit($request->get($form->getName()));
    // or $request->request (for POST)
    // or $request->get (for GET)
    // to be more specific
    

    知道了这一点,你应该就可以使用..

    $form->submit($request->all());
    // again with ->request or ->get to be more specific
    

    .. 将所有请求数据作为实际的表单数据提交,而不需要表单名称作为键。

    这确实意味着任何额外的字段(如果有)也将提交到表单中,并可能导致其中一些“此表单不应包含额外的字段”。

    【讨论】:

      猜你喜欢
      • 2020-11-13
      • 2018-02-13
      • 2014-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多