(已解决)(symfony 5 formbuilder) 如何用 json 数组中的数据填充复选框?

(solved)(symfony5 formbuilder) How to repopulate checkboxes with data from a json array?

用户角色数据在 Postgres 中存储为 json 数组。

例如["ROLE_SUPER_ADMIN","ROLE_3","ROLE_4"]

这是编辑用户的功能。我将检索到的用户对象传递给表单。

public function edit($id, Request $request, TranslatorInterface $translator) {

    $user = $this->getDoctrine()
        ->getRepository(User::class)
        ->find($id);

    if (!$user) {
        throw $this->createNotFoundException();
    }

    $this->denyAccessUnlessGranted("USER_EDIT", $user);

    $form = $this->createForm(UserType::class, $user);

    if (!$this->security->isGranted("ROLE_USER_ADMIN")) {

        $form->remove("roles");
    }

    $form->remove("password");

    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {

        if ($this->security->isGranted("ROLE_USER_ADMIN")) {

            $roles = $form->get("roles")->getData();

            $array= [];

            if ($roles) {

                foreach ($roles as $role) {

                    $array[] = $role->getName();
                }
            }

            $user->setRoles($array);
        }

        $user->setTsModified(new \DateTime());

        $manager = $this->getDoctrine()->getManager();
        $manager->flush();

        $this->addFlash(
            "success",
            $translator->trans("user_edit_success")
        );

        if ($this->security->isGranted("ROLE_USER_ADMIN")) {

            return $this->redirectToRoute("user_list");
        }

        return $this->redirectToRoute("dashboard");
    }

    return $this->render("user/edit.html.twig", [
        "user" => $user,
        "user_edit" => $form->createView()
    ]);
}

这是要填写的 UserType(表单)。我删除了除此 post.

角色 selection 之外的所有数据
class UserType extends AbstractType {

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

        $builder
            ->add("roles", EntityType::class, [
                "class" => Role::class,
                "placeholder" => "select",
                "choice_label" => "name",
                "choice_value" => "name",
                "label" => "roles",
                "expanded" => true,
                "multiple" => true,
                "required" => false,
            ])
            ->add("save", SubmitType::class, ["label" => "save"])
        ;
    }

    public function configureOptions(OptionsResolver $resolver) {

        $resolver->setDefaults([
            "data_class" => User::class,
        ]);
    }
}

它应该像 this 这样填充复选框,但它没有。现在我每次编辑用户时都必须 (re)select 角色,因为没有选中框意味着没有角色 selected(这是有意的)。

我构建的表单是错误的还是在调用 $form = $this->createForm(UserType::class, $user) 之前应该有一些额外的步骤?在编辑功能中?

编辑 2020 年 6 月 8 日

我刚刚注意到 formbuilder 需要 Role 对象,但现在它正在获取字符串。当 selecting 角色时,我只从 Role 对象中获取名称(字符串)(Role 对象包含 id 和 name)。

在构建表单之前必须看看我是否可以将字符串数组转换回 Role 对象。

2020 年 6 月 8 日解决

将 EntityType selection 更改为由 OptionsResolver 填充的 ChoiceType。

用户编辑功能。记得删除 ->getName();来自循环,因为提交的值不再是一个对象而是一个字符串。

$roles1 = $this->getDoctrine()
    ->getRepository(Role::class)
    ->findAll();

foreach ($roles1 as $role) {
    $roles[] = $role->getName();
}

$form = $this->createForm(UserType::class, $user, [
    "roles" => $roles
]);

                foreach ($roles as $role) {

                    $array[] = $role;
                }

用户类型。

    ->add("roles", ChoiceType::class, [
        "choices" => $options["roles"],
        "choice_label" => function($key, $index) {
            return $key;
        },
        "expanded" => true,
        "multiple" => true,
        "required" => false,
        "label" => "roles",
    ])

以及其中的 OptionsResolver 部分。

public function configureOptions(OptionsResolver $resolver) {

    $resolver->setDefaults([
        "data_class" => User::class,
        "roles" => null
    ]);
}

将 EntityType 选择更改为由 OptionsResolver 填充的 ChoiceType。

用户编辑功能。记得删除 ->getName();来自循环,因为提交的值不再是一个对象而是一个字符串。

$roles1 = $this->getDoctrine()
    ->getRepository(Role::class)
    ->findAll();

foreach ($roles1 as $role) {
    $roles[] = $role->getName();
}

$form = $this->createForm(UserType::class, $user, [
    "roles" => $roles
]);

                foreach ($roles as $role) {

                    $array[] = $role;
                }

用户类型。

->add("roles", ChoiceType::class, [
    "choices" => $options["roles"],
    "choice_label" => function($key, $index) {
        return $key;
    },
    "expanded" => true,
    "multiple" => true,
    "required" => false,
    "label" => "roles",
])

以及其中的 OptionsResolver 部分。

public function configureOptions(OptionsResolver $resolver) {

    $resolver->setDefaults([
        "data_class" => User::class,
        "roles" => null
    ]);
}