簡體   English   中英

創建和處理表單后如何設置 Symfony EntityType 表單字段的選項?

[英]How to set the choices of a Symfony EntityType form field after the form has been created and handled?

我正在使用Symfony 3.4並想創建一個簡單的表單,該表單顯示一個列表實體,可以使用復選框選擇刪除:

  • 創建和處理表單的 controller 從數據庫加載實體列表,然后將其添加到表單中。
  • controller 使用一些附加參數來提供分頁,例如,如果數據庫中有 10.000 個實體,用戶可以選擇僅加載前 50 個。

問題是,“前 50 個實體”取決於實體是否已被刪除/表單已被處理。

  • 要處理 controller 中的表單,我必須先創建它
  • 要創建表單,我需要從數據庫加載實體列表以將它們設置為choises
  • 此列表將包含前 50 個實體
  • 如果用戶選擇刪除前 10 個實體,則在處理表單時完成。

class SomeController
{
    public function deleteUsersAction(Request $request)
    {
        $users = $this->loadUsersFromDB(50);

        $form = $this->creatFormBuilder()
            ->add('users', EntityType::class, [
                'class' => 'AppBundle:User',
                'choices' => $users,                  // $users are added here
                'multiple' => true,
                'expanded' => true,
            ])
            ->getForm();

        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            $users = $form->getData();
            $this->deleteUsers($user);

            // Load the now first 50 users
            $users = $this->loadUsersFromDB(50);

            // How to add these users to the form??
        }

        return $this->render('AppBundle::user_list.html.twig', ['form' => $form->createView()]);
    }
}

提交的用戶被刪除后,如何為表單設置正確的用戶?


編輯

為了回答評論中的問題,我提供了一個小例子:

  • 假設表單顯示前 5 個用戶。
  • 當頁面第一次被調用時,表單沒有被提交。 controller 加載以下第一個用戶,使用他們創建表單並顯示頁面:
  • 鮑勃
  • 愛麗絲
  • 麥克風
  • 約翰
  • 賬單
  • 在頁面上,用戶選擇BobAlice進行刪除並提交表單。
  • 再次調用 controller,並加載前 5 個用戶的列表以創建表單。 這個列表和之前的完全一樣。
  • 但是,由於現在提交了表單,因此處理了數據並刪除了 Bob 和 Alice。
  • 現在我們無法返回創建的表單,因為它仍然包含 Bob 和 Alice 的條目......
  • 我們必須再次運行$users = $this->loadUsersFromDB(5)以獲得正確的結果,例如
  • 麥克風
  • 約翰
  • 賬單
  • 吉姆
  • 湯姆

問題:

  • 用戶列表必須在創建表單之前加載,因為我們需要這個列表來創建表單。
  • 必須創建表單以便我們處理它
  • 處理表單確實會更改用戶列表
  • 因此,在處理完表單后,我們需要再次加載用戶列表。

所以:在處理表單之前加載用戶列表是必要的工作,因為處理表單時列表會發生變化。

如何避免這項工作?

當然,在示例中加載 5 個用戶沒什么大不了的,但在實際代碼中,這可能是數百個沉重的實體,並且兩次運行相同的代碼可能會對性能產生重大影響。

我想你沒有理解我在評論中的建議,所以我會在這里更詳細地解釋/現在我也是用筆記本電腦寫的:)/

class SomeController {
    public function deleteUsersAction(Request request) {
        $users = $this->loadUsersFromDB(50);        

        $form = $this->creatFormBuilder()
            ->add('users', EntityType::class, [
                'class' => 'AppBundle:User',
                'choices' => $users,                  // $users are added here
                'multiple' => true,
                'expanded' => true,
            ])
            ->getForm();

         $form->handleRequest($request);
         if ($form->isSubmitted() && $form->isValid()) {
             $users = $form->getData();
             $this->deleteUsers($user);

             // Load the now first 50 users
             $users = $this->loadUsersFromDB(50); <-- you don't need this

             // Q: How to add these users to the form??
             // A: When you return a redirect response to the same page /you can also pass any query parameters if you had any filters and etc../
             //    This will ensure that the page is loaded properly with the new list of the users and Bob and Alice will NOT be in the list
             //    If you don't do it with a redirect and the user submits the form the browser remembers the data and if the users hits the refresh button of the browser it will resubmit the form and with your approach it may delete next 2 users /Mike and John/.
             return $this->redirectToRoute('YOUR_ROUTE', $request->query->all());
         }

         return $this->render('AppBundle::user_list.html.twig', ['form' => $form->createView()]);
    }
}```

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM