Symfony3:如何使用 PATCH 方法将布尔值更新为 false [英] Symfony3: How to update boolean to false using PATCH method

查看:19
本文介绍了Symfony3:如何使用 PATCH 方法将布尔值更新为 false的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个大实体和一个大表格.更新我的实体时,我只通过 ajax 调用呈现表单的一部分.在客户端,我使用 Jquery 和 html5 FormData,所以我也可以在我的表单中发送文件.为了确保未呈现的字段在此过程中不会被设置为 null,我使用了 PATCH 方法.

I have a big entity and a big form. When updating my entity, I only render parts of my form, through ajax calls. On client side, I'm using Jquery and html5 FormData, so I can also send files within my form. To make sure the fields that are not rendered won't be set to null in the process, I'm using PATCH method.

因此,当请求中不存在的字段时,Symfony会保持原样.

So when a field is not present in the request, it's left as is by Symfony.

但是当我更新的字段是设置为 true 的布尔值(呈现 aa 复选框)并且我想将其设置为 false 时,它​​不会在请求中传递,因此我的更新被忽略.

But when the field I update is a boolean (rendered a a checkbox) that was set to true and I want to set it to false, it's not passed in the request, so my update is ignored.

是否有一种简单的方法可以强制在请求中显示未选中的复选框?

Is there an easy way to force unchecked checkboxes to appear in the request?

编辑
由于 Felix Kling 对 这个问题 的评论,我找到了一种强制未选中复选框出现在请求中的方法:

EDIT
I found a way to force unchecked checkboxes to appear in the request, thanks to Felix Kling's comment on this question :

$("input:checkbox:not(:checked)").each(function() {
    formData.set($(this).attr('name'), formData.has($(this).attr('id')) ? '1' : '0');
});  

不幸的是,这并没有解决我的问题,因为 Symfony 的行为:
- 使用 PUT 时,如果布尔字段出现在请求中,则将其设置为 true,无论其值如何(即使它是0"或false").
- 使用 PATCH 方法时,请求中未出现的字段将被忽略.

Unfortunately, this didn't solve my problem, because of Symfony's behaviour:
- When using PUT, if the boolean field appears in the request, it's set to true, regardless of its value (even if it's "0" or "false").
- When using PATCH method, the fields not appearing in the request are ignored.

这可以用 DataTransformer 解决吗?(我没用过)

Could that be solved with DataTransformer? (I've never used it)

推荐答案

这里有一个可行的解决方案,可以改进.

Here goes a working solution, that could be improved.

为了强制在请求中显示未选中的复选框,感谢 Felix Kling 对这个问题的评论,我在 ajax 请求之前添加了这个 js :

To force unchecked checkboxes to appear in the request, thanks to Felix Kling's comment on this question, I've added this js before my ajax request :

$("input:checkbox:not(:checked)").each(function() {
    formData.set($(this).attr('name'), formData.has($(this).attr('id')) ? '1' : '0');
});  

然后,在 Symfony 方面,我不得不覆盖 BooleanToStringTransformer 行为,它为任何字符串返回 true ,而仅为空值返回 false .在最后一行进行更改,如果该值与为 true 定义的值(默认为1")不匹配,我们现在返回 false.因此,如果表单返回的值是0",我们会得到 false,正如预期的那样.

Then, on the Symfony side, I had to override the BooleanToStringTransformer behaviour, that returns true for whatever string and false only for null value. Making a change in the last line, we now return false if the value doesn't match the value defined for true ("1" by default). So if the value returned by the form is "0", we get false, as expected.

public function reverseTransform($value)
{
    if (null === $value) {
        return false;
    }

    if (!is_string($value)) {
        throw new TransformationFailedException('Expected a string.');
    }

    return ($this->trueValue === $value); // initially: "return true;" 
}

文档之后,我制作了自己的DataTransformer,作为以及自定义 AjaxCheckboxType

Following the docs, I made my own DataTransformer, as well as a custom AjaxCheckboxType

不幸的是,Symfony 似乎一个接一个地使用两个 DataTransformer(我的和原始的),所以它没有用.在文档中,他们扩展了 TextType 而不是 CheckboxType,这必须解释我遇到的问题.

Unfortunately, it seems that Symfony uses both DataTransformers (mine and the original one), one after the other, so it didn't work. In the docs they extend TextType not CheckboxType, that must explain the problems I encountered.

我最终将整个 CheckboxType 类 复制并粘贴到我自己的 AjaxCheckboxType 中,只是为了使用我的而更改了 DataTransformer 的调用.

I ended up copying and pasting the whole CheckboxType class in my own AjaxCheckboxType, only changing the DataTransformer's call in order to use mine.

更好的解决方案是完全覆盖 DataTransformer,但我不知道如何.

A much nicer solution would be to totally override the DataTransformer, but I don't know how.

这篇关于Symfony3:如何使用 PATCH 方法将布尔值更新为 false的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆