reactjs 是否可以将Symfony表单组件与React.js一起使用?

aydmsdu9  于 2022-11-04  发布在  React
关注(0)|答案(3)|浏览(215)

我正在使用Symfony表单组件。我的项目中有很多表单。
要完全掌握表单组件还有很长的路要走,但是现在我喜欢它,我也喜欢自动验证等等。
所以,现在我想学习并在我的项目中使用React.js。
但似乎,我没有办法像以前那样使用验证和表单生成器来进行项目?我说得对吗?

w1jd8yoj

w1jd8yoj1#

虽然在API上下文中,您不会使用表单组件以HTML格式($form->createView()方法)实际呈现表单,但您仍然可以从它提供得所有神奇功能中获益:验证、表单事件等。无论是否是API,我个人认为您应该始终在控制器变体中使用表单类型。
例如,使用FOSRestBundle时,请考虑一些简单的控制器操作,如下所示:

/**
 * @Rest\Put("posts/edit/{id}", name="posts.edit", requirements={"id"="\d+"})
 *
 * @param Post $post
 * @param Request $request
 *
 * @return Post
 *
 * @throws BadRequestException
 *
 */
public function edit(Post $post, Request $request): Post
{
    $form = $this->createForm(PostType::class, $user);
    $form->handleRequest($request);
    $form->submit($request->request->all());
    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $em->persist($post);
        $em->flush();

        return $post;
    }

    // Any error handling of your taste.
    // You could consider expliciting form errors.
    throw new BadRequestException();
}

注意,当然,必须创建Post实体和PostType表单。我不会在这里详细说明,因为在这个上下文中没有什么特别的东西要说。
另外请注意,我们不会检查表单是否已提交。在您的案例中,React的工作是将表单呈现为HTML,此操作不会用于GET任何内容,它是一个专用的PUT路径。这意味着任何到达那里的请求都必须是包含正确数据的PUT请求,才能由我们的PostType处理,在您的案例中,是通过React中手动构建的HTML表单提交的。
此外,稍微超出问题范围的是,FOSRestBundle订阅您的操作返回的任何内容,并自动将其序列化为配置的格式(我猜,在您的情况下,假设是JSON)。

  • 包含序列化Post的状态代码为200的响应。(您也可以考虑204,不返回任何内容。)
  • 一个状态代码为400的响应,包含我们想要的任何内容(比如表单错误)。

请允许我带你去FOSRestBundle's documentation

vhipe2zx

vhipe2zx2#

可能不是,因为您的表单是供服务器用途:验证/显示错误/数据标准化/净化/等。
通常,您使用React显示HTML并使用API将其连接到服务器。

5vf7fwbs

5vf7fwbs3#

您可以毫无问题地使用formBuilder创建的表单。
您必须使用axios获取表单并创建一个新组件,如下所示:

const url = 'localhost/post/new';
const ref = useRef(null);

const [form, setForm] = useState('');    
const fetchData = () => {
        axios.get(url))
            .then(function (response){
                setForm(response.data);
            })
            .catch(function (error){
                //something
            })
        ;
    }

const MyComponent = () => {
        useEffect(() => {
            const element = ref.current.firstChild;
            if (ref.current.firstChild === null)
                return;

            element.addEventListener('submit', () => {handleSave(event)});
            return () => {
                element.removeEventListener('submit', () => {handleSave(event)});
            };
        }, []);

        return (
            <div ref={ref} dangerouslySetInnerHTML={{ __html: form }} />
        );
    };

const handleSave = (event) => {
        event.preventDefault();
        let formData = new FormData(event.target)
        let action = event.target.action;
        let files = event.target.querySelectorAll('[type="file"]');
        if (files)
            files.forEach((file) => {
                formData.set(file.name, file.files[0])
            });
        axios.post(action, formData)
            .then(function (response) {
                Swal.fire({
                    icon: 'success',
                    title: response.data.message,
                    showConfirmButton: false,
                    timer: 1500
                })
            //Do something else
            })
            .catch(function (error) {
                error.response.status === 422 ?
                    setForm(error.response.data)
                    :
                    console.log(error);
            });
    }

return (<MyComponent/>);

因此,现在您可以获得带有html组件的表单,并使用React组件呈现它。
如果出现一些验证错误,则会得到422状态,并且可以用setForm()替换表单。
在Symfony控制器中,您必须进行如下设置:


# [Route('/post/{state}/{id}', name: 'post', defaults: ['state' => null, 'id' => null])]

public function post(
    ?string $state,
    ?int $id,
    Request $request,
    EntityManagerInterface $em
): JsonResponse|Response
{
    if ($state == 'new') {
        $post = new Post();
        $form = $this->createFormBuilder()
            ->add('title', TextType::class)
            ->add('content', TextareaType::class);

        $form = $form->getForm();
        $form->handleRequest($request);
        if ($form->isSubmitted() and $form->isValid()) {
            $em->persist($post);
            $em->flush();

            return $this->json(['message' => 'post added!'], 200);
        }

        return $this->renderForm('{{ form(form) }}', [
            'form' => $form
        ]);
    }
}

我已经减少了功能只为形式,但你可以使用它为您的所有要求。

相关问题