对象 "Symfony\Component\Form\FormView" 的方法 "username" 在第 11 行的 admin/user/_form.html.twig 中不存在

Method "username" for object "Symfony\Component\Form\FormView" does not exist in admin/user/_form.html.twig at line 11

几周以来我一直有问题。 我在 Google 和 Symfony 文档上搜索了很多,但没有找到解决方案。

问题是我总是收到此错误消息:

Method "username" for object "Symfony\Component\Form\FormView" does not exist in admin/user/_form.html.twig at line 11

但不是每个 FormType

比如我的Field Entity就没有问题。但是我的 User 或 CompanyType 有这个问题。当我在 twig 中 dump(form) 时,一切正常,我可以看到像用户名这样的变量。它也显示在 Profiler 中。我比较了一个功能正常的和一个功能不正常的。据我所知,它们是相同的。

同样奇怪的是,当我渲染整个表单时

form_row(form) 它正在运行。 form_row(form.username) 不是。

我正在使用 Symfony 2.7.9

如果您现在还需要其他东西,请告诉我。 抱歉,我是第一次主动提问。

提前感谢您的帮助。

此致, 凯文

编辑代码:

<?php

namespace ITGruber\HektMan\AdminBundle\Form;

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

/**
* Defines the form used to create and manipulate machine posts.
*
* @author Kevin <office@it-gruber.com>>
*/
class JobType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('reply', 'entity', array(
                'class' => 'ITGruber\HektMan\AdminBundle\Entity\User',
                'choice_label' => 'username',
                'label' => 'label.reply_to'
            ))
            ->add( 'dueDate', 'date', array(
                'widget' => 'single_text',
                'label' => 'label.duedate',
            ))
            ->add('listed', null, array('label' => 'label.listed'))
            ->add('salary', 'money', array(
                'label' => 'label.salary',
                'grouping' => true,
                'mapped' => false,
            ))
            ->add('machines', 'entity', array(
                'class' => 'ITGruber\HektMan\AdminBundle\Entity\Machine',
                'choice_label' => 'name',
                'label' => 'label.machine',
                'expanded' => true,
                'multiple' => true,
            ))
        ;
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'ITGruber\HektMan\AdminBundle\Entity\Job',
        ));
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'app_job';
    }
}

工作实体

<?php

/**
 * This file is part of the hekt-man package.
 *
 * (c) Kevin <office@it-gruber.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * Created by PhpStorm.
 * Project: hekt-man
 * User: Kevin
 * Date: 14.02.16
 * Time: 03:45
 * Version: 1.0
 * Dir: ITGruber\HektMan\AdminBundle\Entity
 */

namespace ITGruber\HektMan\AdminBundle\Entity;


use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity(repositoryClass="ITGruber\HektMan\AdminBundle\Repository\JobRepository")
 * @ORM\Table(name="job")
 *
 * @author Kevin <office@it-gruber.com>
 */
class Job
{
    /**
     * Constant
     */
    const NUM_ITEMS = 10;

    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="User", inversedBy="jobs")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=TRUE)
     */
    protected $user;

    /**
     * @ORM\ManyToOne(targetEntity="Company", inversedBy="jobs")
     * @ORM\JoinColumn(name="company_id", referencedColumnName="id", nullable=FALSE)
     */
    protected $company;

    /*
    /**
     * @ORM\ManyToMany(targetEntity="Machine", inversedBy="jobs", fetch="EAGER")
     * @ORM\JoinTable(name="job_machine")
     **/
    protected $machines;

    /**
     * @ORM\ManyToOne(targetEntity="Field")
     * @ORM\JoinColumn(name="field_id", referencedColumnName="id", nullable=FALSE)
     */
    protected $field;

    /**
     * @ORM\Column(type="datetime")
     * @Assert\DateTime()
     */
    protected $dueDate;

    /**
     * @ORM\Column(type="float")
     */
    protected $salary;

    /**
     * @ORM\ManyToOne(targetEntity="User")
     * @ORM\JoinColumn(name="reply_id", referencedColumnName="id", nullable=FALSE)
     */
    protected $reply;

    /**
     * @ORM\Column(type="boolean")
     */
    protected $listed;

    /**
     * @ORM\Column(type="datetime")
     * @Assert\DateTime()
     */
    protected $dateCreated;

    /**
     * @ORM\Column(type="datetime")
     * @Assert\DateTime()
     */
    protected $dateModified;


    /**
     * Job constructor.
     */
    public function __construct()
    {
        $this->machines = new ArrayCollection();
        $this->dateCreated = new \DateTime();
    }

    /**
     * Gets ID
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Gets User
     *
     * @return User
     */
    public function getUser()
    {
        return $this->user;
    }

    /**
     * Sets User
     *
     * @param User $user
     */
    public function setUser(User $user)
    {
        $this->setDateModified(new \DateTime());
        $this->user = $user;
        if($user !== null) {
            $user->addJob($this);
        }
    }


    /**
     * Remove User
     *
     * @param User $user
     */
    public function removeUser(User $user)
    {
        $this->setDateModified(new \DateTime());
        $this->user = null;
        if($user !== null) {
            $user->removeJob($this);
        }
    }


    /**
     * Gets Company
     *
     * @return Company
     */
    public function getCompany()
    {
        return $this->company;
    }

    /**
     * Sets Company
     *
     * @param Company $company
     */
    public function setCompany(Company $company)
    {
        $this->setDateModified(new \DateTime());
        $this->company = $company;
        if($company !== null) {
            $company->addJob($this);
        }
    }

    /**
     * Remove Company
     *
     * @param Company $company
     */
    public function removeCompany(Company $company)
    {
        $this->setDateModified(new \DateTime());
        $this->company = null;
        if($company !== null) {
            $company->removeJob($this);
        }
    }

    /**
     * Gets List of associated Machines
     *
     * @return Machine[]
     */
    public function getMachines()
    {
        //return $this->machines->toArray();
    }

    /**
     * Add Machine
     *
     * @param Machine $machine
     * @return Job
     */
    public function addMachine(Machine $machine)
    {
        if (!$this->machines->contains($machine)) {
            $this->machines->add($machine);
            $this->setDateModified(new \DateTime());
            $machine->addJob($this);
        }
        return $this;
    }


    /**
     * Clears Machines
     *
     * @return Job
     */
    public function clearMachines()
    {
        $this->machines->clear();
        $this->setDateModified(new \DateTime());

        return $this;
    }

    /**
     * Remove Machine
     *
     * @param Machine $machine
     * @return Job
     */
    public function removeMachine(Machine $machine)
    {
        if ($this->machines->contains($machine)) {
            $this->machines->removeElement($machine);
            $this->setDateModified(new \DateTime());
            $machine->removeJob($this);
        }
        return $this;
    }

    /**
     * Set Machines
     *
     * @param Machine[] $machines
     */
    public function setMachines($machines)
    {
        $this->setDateModified(new \DateTime());
        $this->machines = $machines;
    }

    /**
     * Gets Field
     *
     * @return Field
     */
    public function getField()
    {
        return $this->field;
    }

    /**
     * Sets Field
     *
     * @param Field $field
     */
    public function setField(Field $field)
    {
        $this->setDateModified(new \DateTime());
        $this->field = $field;
    }

    /**
     * Gets Due Date
     *
     * @return \DateTime
     */
    public function getDueDate()
    {
        return $this->dueDate;
    }

    /**
     * Sets duedate
     *
     * @param \DateTime $dueDate
     */
    public function setDueDate(\DateTime $dueDate)
    {
        $this->setDateModified(new \DateTime());
        $this->dueDate = $dueDate;
    }

    /**
     * Gets salary for job
     *
     * @return float
     */
    public function getSalary()
    {
        return $this->salary;
    }

    /**
     * Sets Salary for Job
     *
     * @param float $salary
     */
    public function setSalary($salary)
    {
        $this->setDateModified(new \DateTime());
        $this->salary = $salary;
    }

    /**
     * Returns User object to reply-to
     *
     * @return User
     */
    public function getReply()
    {
        return $this->reply;
    }

    /**
     * Sets the User for reply-to
     *
     * @param User $reply
     */
    public function setReply($reply)
    {
        $this->setDateModified(new \DateTime());
        $this->reply = $reply;
    }

    /**
     * Gets if job is listed
     *
     * @return boolean
     */
    public function isListed()
    {
        return $this->listed;
    }

    /**
     * Sets job as listd
     *
     * @param boolean $listed
     */
    public function setListed($listed)
    {
        $this->setDateModified(new \DateTime());
        $this->listed = $listed;
    }

    /**
     * Get DateModified
     *
     * @return \DateTime
     */
    public function getDateModified()
    {
        return $this->dateModified;
    }

    /**
     * Set DateModified
     *
     * @param \DateTime $dateModified
     */
    public function setDateModified($dateModified)
    {
        $this->dateModified = $dateModified;
    }

    /**
     * Get DateCreated
     *
     * @return \DateTime
     */
    public function getDateCreated()
    {
        return $this->dateCreated;
    }

    /**
     * Set DateCreated
     *
     * @param \DateTime $dateCreated
     */
    public function setDateCreated($dateCreated)
    {
        $this->setDateModified(new \DateTime());
        $this->dateCreated = $dateCreated;
    }
}

作业控制器

<?php
/**
 * This file is part of the hekt-man package.
 *
 * (c) Kevin <office@it-gruber.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * Created by PhpStorm.
 * Project: hekt-man
 * User: Kevin
 * Date: 15.02.16
 * Time: 15:20
 * Version: 1.0
 * Dir: ITGruber\HektMan\AdminBundle\Entity
 */

namespace ITGruber\HektMan\AdminBundle\Controller\Admin;


use ITGruber\HektMan\AdminBundle\Entity\Company;
use ITGruber\HektMan\AdminBundle\Entity\Job;
use ITGruber\HektMan\AdminBundle\Form\JobType;
use ITGruber\HektMan\AdminBundle\Pagination\Paginator;
use Symfony\Component\Form\Form;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\HttpFoundation\Response;


/**
 * Controller used to manage jobs in the admin backend.
 *
 * @Route("/job")
 * @Security("has_role('ROLE_ADMIN')")
 *
 * @author Kevin <office@it-gruber.com>
 */
class JobController extends Controller
{
    /**
     * Lists all Job entities but only TableHeaders
     *
     * @Route("/", name="admin_job_index")
     * @Method({"GET"})
     * @Security("has_role('ROLE_ADMIN')")
     *
     * @return Response
     */
    public function indexAction()
    {
        $em = $this->getDoctrine()->getManager();
        $entities_count = $em->getRepository('ITGruber\HektMan\AdminBundle\Entity\Job')->counterCompany($this->getUser()->getCurrentCompany()->getId());

        return $this->render('ITGruberHektManAdminBundle:admin:job/index.html.twig', array(
            'entitiesLength' => $entities_count,
            'company' => $this->getUser()->getCurrentCompany(),
            'current_company' => $this->getUser()->getCurrentCompany(),
            'include_back_to_home_link' => false,
            'perPage' => Job::NUM_ITEMS,
            'render_assigned' => false));
    }

    /**
     * Lists all Job entities which belongs to the given Company but only TableHeaders
     *
     * @Route("/company/{id}", name="admin_job_company_index")
     * @Method({"GET"})
     * @Security("has_role('ROLE_ADMIN')")
     *
     * @param Company $company
     * @return Response
     */
    public function indexActionWithCompany(Company $company)
    {
        $em = $this->getDoctrine()->getManager();
        $entities_count = $em->getRepository('ITGruber\HektMan\AdminBundle\Entity\Job')->counterCompany($company->getId());

        return $this->render('ITGruberHektManAdminBundle:admin:job/index.html.twig', array(
            'company' => $company,
            'current_company' => $this->getUser()->getCurrentCompany(),
            'entitiesLength' => $entities_count,
            'include_back_to_home_link' => false,
            'render_assigned' => false));
    }


    /**
     * Returns a list of all Job entities via an ajax response
     *
     * @Route("/ajaxList", name="ajax_admin_job_index")
     * @Method({"POST"})
     * @Security("has_role('ROLE_ADMIN')")
     *
     * @param Request $request
     * @return Response
     */
    public function ajaxListAction(Request $request)
    {
        $em = $this->getDoctrine()->getManager();
        $searchParam = $request->get('searchParam');

        $entities = $em->getRepository('ITGruber\HektMan\AdminBundle\Entity\Job')->search($searchParam, $this->getUser()->getCurrentCompany());

        if (!array_key_exists('company', $searchParam)) {
            $entities_count = $em->getRepository('ITGruber\HektMan\AdminBundle\Entity\Job')->counterCompany($this->getUser()->getCurrentCompany()->getId());
            $render_assigned = true;
        } else {
            $entities_count = $em->getRepository('ITGruber\HektMan\AdminBundle\Entity\Job')->counterCompany($searchParam['company']);
            $render_assigned = false;
        }
        $pagenator = (new Paginator())->setItems(count($entities), $searchParam['perPage'])->setPage($searchParam['page']);
        $pagination = $pagenator->toArray();

        return $this->render('ITGruberHektManAdminBundle:admin:job/ajax_list.html.twig', array(
            'jobs' => $entities,
            'pagination' => $pagination,
            'count' => $entities_count,
            'current_company' => $this->getUser()->getCurrentCompany(),
            'render_assigned' => $render_assigned,
            'include_back_to_home_link' => false,
            'page' => $pagenator->getPage(),
            'perPage' => $searchParam['perPage']
        ));
    }


    /**
     * Creates a new Job entity.
     *
     * @Route("/new", name="admin_job_new")
     * @Method({"GET"})
     * @Security("has_role('ROLE_ADMIN')")
     *
     * @param Request $request
     * @return Response
     */
    public function newAction(Request $request)
    {
        $job = new Job();
        $job->setDateCreated(new \DateTime());
        $job->setDateModified(new \DateTime());
        $form = $this->createForm(new JobType(), $job);

        $form->handleRequest($request);

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

            $em = $this->getDoctrine()->getManager();

            $em->persist($job);

            $em->flush();

            $this->get( 'session' )->getFlashBag()->add( 'status', 'created' );
            return $this->redirectToRoute('admin_job_index');
        }

        return $this->render('ITGruberHektManAdminBundle:admin:job/new.html.twig', array(
            'job' => $job,
            'form' => $form->createView(),
        ));
    }

    /**
     * Finds and displays a Job entity.
     *
     * @Route("/{id}", requirements={"id" = "\d+"}, name="admin_job_show")
     * @Method("GET")
     * @Security("has_role('ROLE_ADMIN')")
     *
     * @param Job $job
     * @return Response
     */
    public function showAction(Job $job)
    {
        $deleteForm = $this->createDeleteForm($job);

        return $this->render('ITGruberHektManAdminBundle:admin:job/show.html.twig', array(
            'is_admin' => $this->getUser()->isAdmin($job),
            'job' => $job,
            'delete_form' => $deleteForm->createView(),
        ));
    }


    /**
     * Creates a form to delete a Field job by id.
     *
     * @param Job $job
     *
     * @return Form
     */
    private function createDeleteForm(Job $job)
    {
        return $this->createFormBuilder()
            ->setAction($this->generateUrl('admin_job_delete', array('id' => $job->getId())))
            ->setMethod('DELETE')
            ->getForm();
    }

    /**
     * Displays a form to edit an existing Job entity.
     *
     * @Route("/{id}/edit", requirements={"id" = "\d+"}, name="admin_job_edit")
     * @Method({"GET", "POST"})
     * @Security("has_role('ROLE_ADMIN')")
     *
     * @param Job $job
     * @param Request $request
     *
     * @return Response
     */
    public function editAction(Job $job, Request $request)
    {
        $em = $this->getDoctrine()->getManager();

        $editForm = $this->createForm(new JobType(), $job);

        $deleteForm = $this->createDeleteForm($job);

        $editForm->handleRequest($request);

        if ($editForm->isSubmitted() && $editForm->isValid()) {
            $job->setDateModified(new \DateTime());
            $em->flush();

            $this->get( 'session' )->getFlashBag()->add( 'status', 'edited' );
            return $this->redirectToRoute('admin_job_show', array('id' => $job->getId()));
        }

        return $this->render('ITGruberHektManAdminBundle:admin:job/edit.html.twig', array(
            'job' => $job,
            'edit_form' => $editForm->createView(),
            'delete_form' => $deleteForm->createView(),
        ));
    }


    /**
     * Deletes multiple Job etnrys
     *
     * @Route("/remove", name="admin_job_remove")
     * @Security("has_role('ROLE_ADMIN')")
     *
     * @param Request $request
     * @return Response
     */
    public function removeAction(Request $request)
    {
        $ids = $request->get('entities');
        $em = $this->getDoctrine()->getManager();
        $entities = $em->getRepository('ITGruber\HektMan\AdminBundle\Entity\Job')->search(array('ids' => $ids));
        foreach ($entities as $entity) $em->remove($entity);
        $em->flush();

        return new JsonResponse(array('status' => 1));
    }

    /**
     * Deletes a Job entity.
     *
     * @Route("/{id}", name="admin_job_delete")
     * @Method("DELETE")
     * @Security("has_role('ROLE_ADMIN')")
     *
     * @param Request $request
     * @param Job $job
     *
     * @return RedirectResponse
     */
    public function deleteAction(Request $request, Job $job)
    {
        if (null === $this->getUser()) {
            throw $this->createAccessDeniedException('Yard can only be deleted by admins or manager.');
        }

        $form = $this->createDeleteForm($job);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $em = $this->getDoctrine()->getManager();

            $em->remove($job);
            $em->flush();
        }

        $this->get( 'session' )->getFlashBag()->add( 'status', 'deleted' );
        return $this->redirectToRoute('admin_job_index');
    }
}

工作表:

{{ form_start(form) }}

   {{ form_errors(form) }}
   {{ form_row(form.listed) }}

    <input type="submit" value="{{ button_label|default('action.create'|trans) }}"
           class="{{ button_css|default("btn btn-primary") }}" />

    {% if include_back_to_home_link is not defined or include_back_to_home_link == true %}
        <a href="{{ path('admin_job_index') }}" class="btn btn-link">
            {{ 'action.back'|trans }}
        </a>
    {% endif %}
{{ form_end(form) }}

{#{% form_theme form 'form/checkbox.html.twig' %}#}
{#
    {{ form_row(form.reply) }}
    {{ form_row(form.dueDate) }}


    <div>
        {{ form_widget(form.listed) }}
        {{ form_label(form.listed) }}
        {{ form_errors(form.listed) }}
    </div>
    {{ form_row(form.salary) }}
    {{ form_row(form.machines) }}

#}

您的 Job 实体上的 choice_label option must either be a callable function or a string that relates to a property path。您的实体没有名为 getUsername() 的函数,并且没有 public 属性 for $username.

假设您的 User 实体有一个 getUsername() 函数,您可以将以下函数添加到您的 Job 实体:

public function getUsername()
{
    return ($this->user) ? $this->user->getUsername() : null;
}

感谢大家的帮助,我刚刚找到了问题的解决方案。 问题是在控制器中我从同一个 _form.html.twig 模板渲染 DeleteFormEditForm

当我有一个要删除的模板时,form_widget(form)

和行分开的 _form,一切都按预期工作。

希望你能从我的失败中吸取教训。