2014-03-07 36 views
1

我有一個表單,其中有一個User實體項目。如何訪問視圖中的實體

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder->add('user', 'entity', array(/* ... */)); 
} 

我想訪問我的模板中的實體的方法。例如,在一個用戶列表,其中管理員可以選擇一些用戶,誰不是管理員,並從數據庫中刪除:

{% block body %} 
{% for user in form.user %} 
    {% if user.isAdmin %} 
     {# Disable the checkbox #} 
    {% else %} 
     {# Render normally #} 
    {% endif %} 
{% endfor %} 
{% endblock %} 

然而,當我跑我的應用程序,Symfony的告訴我,這個方法isAdmin不存在於對象Symfony\Component\Form\FormView

我一直沒有找到任何解決方案(嘗試使用user.vars.value)。有沒有辦法做到這一點?

編輯:我正在使用Symfony 2.4.2。

+0

對於用戶自定義[0] .isAdmin,用戶[1] .isAdmin? – repincln

+0

你的symfony版本是什麼? – MSadura

+0

@MarkS它是2.4.2。 – pikachu0

回答

1

您不必將用戶轉到您的視圖。 只需創建一個啓用了多個選項的用戶類型,並在提交時執行您想要執行的操作。 以下代碼尚未經過測試。

class UsersType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->add('users', 'entity', array(
      'required'  => false, 
      'class'   => 'MeMyBundle:UserEntity', 
      'property'  => 'id', 
      'property_path' => '[id]', # in square brackets! 
      'multiple'  => true, 
      'expanded'  => true 
     )); 
    } 
} 

創建您的控制器動作

/** 
* @Route("/my_users", name="_users") 
* @Template() 
*/ 
public function usersAction() 
{ 
    $request = $this->get('request'); 
    $users = $this->get('my_user_manager')->findAll() //get all users. Fit this line depending on your app. 
    $form = $this->createForm(new UsersType(), $users); // I assume you have a UsersType here. 

    $form->bind($request); 
    if ($form->isValid()) { 
     $data = $form->getData(); 
     foreach ($data['users'] as $user) { 
      // Do what you want with $user, it contains one selected user 
     } 
     //you can redirect here 
    } 

    return array(
     'users' => $users, 
     'form' => $form->createView(), 
    ); 
} 

現在,在您看來,您可以選擇您的用戶:

{% block body %} 
{% if is_granted('ROLE_ADMIN') %} 
    {{ form_start(form) }} 
     {{ form_errors(form) }} 
     ... 
     <input type="submit" /> 
    {{ form_end(form) }} 
{% else %} 
     {# Render a list #} 
     <ul> 
     {% for user in users %} 
      <li>{{user.username}}</li> 
     {% endfor %} 
     </ul> 
{% endif %} 
{% endblock %} 
+1

此解決方案的問題在於,您必須爲所有用戶查詢兩次(一次在表單構建器中,一次在控制器邏輯中),並在如果您有更復雜的查詢,則必須在多個位置維護代碼。 – ferdynator

+0

您的解決方案有效,但按照@ferdynator的說法,它會爲所有用戶查詢兩次。我會將此標記爲現在的答案,直到有更好的答案。 – pikachu0

+3

您不必爲所有用戶查詢兩次。當你有'用戶'變量時,只需使用它創建你的表單,並將用戶和表單傳遞給你的視圖。我修改我的代碼 –

0

我覺得去最好的辦法是Custom Form Type。因此,在當前的形式使用:

$builder->add('user', 'user', array(/* ... */)); 

,並創建自己UserType

{# src/Acme/DemoBundle/Resources/views/Form/fields.html.twig #} 
{% block user_widget %} 
    {# This will check a value when the user is admin: #} 
    {% set is_selected is_admin %} 
    {# let the original widget do the rest: #} 
    {{ block('choice_widget') }} 
{% endblock %} 

還要確保:

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\OptionsResolver\OptionsResolverInterface; 

class UserType extends AbstractType 
{ 

    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     // ... implement your logic... 
    } 

    public function buildView(FormView $view, FormInterface $form, array $options) 
    { 
     // here you can set the isAdmin value 
     // $view->vars['is_admin'] 
     // you can access your data via $form->getData() 
    } 

    public function getParent() 
    { 
     return 'choice'; 
    } 

    public function getName() 
    { 
     return 'user'; 
    } 
} 

現在你可以基於創建自己的模板將此添加到您的config.yml

twig: 
    form: 
     resources: 
      - 'AcmeDemoBundle:Form:fields.html.twig' 
+0

對不起,我現在正在關閉,因此沒有時間測試您的解決方案,只是一個簡單的問題:我真的必須創建'user_widget'嗎? – pikachu0

+0

只是想添加一個替代方法。不,你不需要。由於'user_widget'擴展了'choice_widget',所以仍然會有一個有效的輸出。但是,由於您重寫了自定義模板中的'is_selected'屬性,這是有道理的。 – ferdynator

0

另一個答案(未測試):

/** 
* @Route("/my_users", name="_users") 
* @Template() 
*/ 
public function usersAction() 
{ 
    $request = $this->get('request'); 
    $users = $this->get('my_user_manager')->findAll() //get all users. Fit this line depending on your app. 

    if ("POST" === $request->getMethod()) { 
     $data = $request->request->get('users'); 
     //Do what you want with submitted data 
    } 

    return array(
     'users' => $users, 
    ); 
} 

您的看法:

{% block body %} 
<form action="{{ path("_users") }}" method="post"> 
    <table> 
     <caption>Users</caption> 
     <thead> 
      <tr> 
      {% if is_granted('ROLE_ADMIN') %} 
      <th>Is admin?</th> 
      {% endif %} 
      <th>Username</th> 
      </tr> 
     </thead> 
     <tbody> 
      <tr> 
      {% if is_granted('ROLE_ADMIN') %} 
      <td> 
       <input class="{% if user.isAdmin() %}admin{% else %}notadmin{% endif %}" type="checkbox" id="user_{{user.getId()}}" name="users[]" value="{{user.getId()}}"{% if user.isAdmin() %} checked{% endif %} /> 
      </td> 
      {% endif %} 
      <td>{{user.getUsername()}}</td> 
      </tr> 
     </tbody> 
    </table> 
    <input type="submit" /> 
</form> 
{% endblock %}