Symfony 2:多种形式生成的对象列表 [英] Symfony 2: Multiple forms generated list of objects

查看:19
本文介绍了Symfony 2:多种形式生成的对象列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想生成包含用户名列表的页面,并且在每个用户旁边我想有一个按钮来激活/停用该用户.

I would like to generate page with list of users names and next to every user I would like to have button which would activate/deactivate this user.

我当然可以在控制器中创建带有用户 ID 和 GET 方法的链接,当点击链接时,它会执行操作.据我所知,出于安全考虑,不建议这样做.因此,我希望使用表单和按钮来向 PUT 路由提交请求,从而更改用户状态,而不是链接到执行操作的路由.

I could of course create link with user ID and GET method in controller which would perform operation when link would be clicked. As far as I know it is not recommended though to do it this way due to security concerns. So instead of links to route which would perform operation I would like to have forms and buttons to submit request to PUT route which would change user status.

问题:如何根据 Doctrine 返回的用户列表生成此类表单(按钮)?

QUESTION: how to generate such forms (buttons) based on list of users returned by Doctrine?

用于在用户配置文件中创建表单/按钮的表单代码:

Form code used to create form/button in user profile:

    /**
 * Creates a form to activate/deactivate a User entity by id.
 *
 * @param mixed $id The entity id
 *
 * @return \Symfony\Component\Form\Form The form
 */
private function createActivationDeactivationForm($id)
{
    return $this->createFormBuilder()
        ->setAction($this->generateUrl('user_activate', array('id' => $id)))
        ->setMethod('PUT')
        ->add('submit', 'submit', array('label' => 'Activate/Deactivate'))
        ->getForm()
    ;
} 

用于用户配置文件的控制器代码:

Controller code used for user profile:

    /**
 * @Route("/user/{id}", name="user_show")
 * @Method("GET")
 * @Template()
 */
public function showUserAction($id)
{
    $em = $this->getDoctrine()->getManager();

    $user = $em->getRepository('TestUserBundle:User')->find($id);

    if (!$user) {
        throw $this->createNotFoundException('Unable to find user');
    }

    $deleteForm = $this->createDeleteForm($id);                
    $activateForm = $this->createActivationDeactivationForm($id);                

    return array(
        'user' => $user,
        'delete_form' => $deleteForm->createView(),
        'activate_form' => $activateForm->createView(),

    );
}

从用户配置文件执行操作的控制器 PUT 方法:

Controller PUT method to perform operation from user profile:

    /**
 * Activate a user.
 *
 * @Route("/{id}", name="user_activate")
 * @Method("PUT")
 */
public function activateAction(Request $request, $id)
{
    $form = $this->createActivationDeactivationForm($id);
    $form->handleRequest($request);

    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $user = $em->getRepository('TestUserBundle:User')->find($id);

        if (!$user) {
            throw $this->createNotFoundException('Unable to find user');
        }

        $current_user_activity_flag = $user->getActive();

        $user->setActive(abs($current_user_activity_flag-1));

        $em->persist($user);
        $em->flush();
    }

    return $this->redirect($this->getRequest()->headers->get('referer'));
} 

用于用户列表的控制器代码:

Controller code to be used for users list:

    /**
 * @Route("/users", name="users_list")
 * @Method("GET")
 * @Template()
 */
public function listUsersAction()
{
    $em = $this->getDoctrine()->getManager();

    $users = $em->getRepository('TestUserBundle:User')->findExistingUsers();

    //$deleteForm = $this->createDeleteForm($id);                
    //$activateForm = $this->createActivationDeactivationForm($id);                

    return array(
        'users' => $users,
        //'delete_form' => $deleteForm->createView(),
        //'activate_form' => $activateForm->createView(),

    );
}

我无法将 ID 传递给表单,就像我从配置文件操作时所做的那样,因为每个用户都有不同的 ID,而且更多的是 Symfony 只生成第一个表单并忽略其余部分.

I can not pass ID to form like I did for operation from profile cause for every user there is different ID and more of that Symfony generates only first form and ignores rest.

知道如何处理吗?或者我对表单/按钮的处理方式不正确,我应该只使用链接?

Any idea how to handle it? Or maybe my approach with form/buttons is incorrect and I should just use links instead?

推荐答案

我找到了可行的解决方案,但我不确定它是否符合最佳实践.

I found solution which works though I am not sure about if it's compliant with best practices.

我没有在控制器中传递一个表单对象,而是根据用户 ID 生成了一个带有键的数组.比在 TWIG 模板中循环数组时,我使用用户 ID 来引用为当前用户创建的表单对象.

Instead of passing one form object in controller I generated an array of them with keys based on user ID. Than when looping through array in TWIG template I use user ID to refer form object created for current user.

提到的用户列表问题控制器应该看起来像这样:

Mentioned in question controller for user listing should than look like this:

    /**
 * @Route("/users", name="users_list")
 * @Method("GET")
 * @Template()
 */
public function listUsersAction()
{
    $em = $this->getDoctrine()->getManager();

    $users = $em->getRepository('PSUserBundle:User')->findExistingUsers();

    $activate_forms = array();
    $delete_forms = array();

    foreach($users as $user)
    {

        $activate_forms[$user->getId()] = $this->createActivationDeactivationForm($user->getId())->createView();
        $delete_forms[$user->getId()] = $this->createDeleteForm($user->getId())->createView();
    }

    return array(
        'users' => $users,
        'delete_forms' => $delete_forms,
        'activate_forms' => $activate_forms,

    );
}

... 并且在 foreach 中的 TWIG 形式应该是这样引用的:

... and in TWIG form within foreach should be refered like this:

    {{ form_start(activate_forms[user.id], {'attr': {'novalidate': 'novalidate'}}) }}

        {% if user.active %}
            {{ form_widget(activate_forms[user.id].submit, {'attr': {'class': 'btn btn-xs btn-warning btn-block'}, 'label' : 'Deactivate'}) }}
        {% else %}
            {{ form_widget(activate_forms[user.id].submit, {'attr': {'class': 'btn btn-xs btn-success btn-block'}, 'label' : 'Activate'}) }}
        {% endif %}


     {{ form_end(activate_forms[user.id]) }}  

这篇关于Symfony 2:多种形式生成的对象列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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