我有一个与学说一起使用的ZF2应用程序。我有以下实体:
class Role
{
/**
* @var int
* @ORMId
* @ORMColumn(type="integer")
* @ORMGeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var string
* @ORMColumn(type="string", length=255, unique=true, nullable=true)
*/
protected $name;
/**
* @var ArrayCollection
* @ORMOneToMany(targetEntity="YrmUserEntityRole", mappedBy="parent")
*/
protected $children;
/**
* @var Role
* @ORMManyToOne(targetEntity="YrmUserEntityRole", inversedBy="children", cascade={"persist"})
* @ORMJoinColumn(name="parent_id", referencedColumnName="id")
*/
protected $parent;
}
对于这个实体,我有一个形式:
class RoleForm extends Form
{
/**
* [init description]
*
* @return void
*/
public function init()
{
$this->setHydrator(
new DoctrineHydrator($this->objectManager, 'YrmUserEntityRole')
)->setObject(new Role());
$this->setAttribute('method', 'post');
$this->add(
array(
'name' => 'name',
'attributes' => array(
'type' => 'text',
'placeholder' =>'Name',
),
'options' => array(
'label' => 'Name',
),
)
);
$this->add(
array(
'type' => 'DoctrineModuleFormElementObjectSelect',
'name' => 'parent',
'attributes' => array(
'id' => 'parent_id',
),
'options' => array(
'label' => 'Parent',
'object_manager' => $this->objectManager,
'property' => 'name',
'is_method' => true,
'empty_option' => '-- none --',
'target_class' => 'YrmUserEntityRole',
'is_method' => true,
'find_method' => array(
'name' => 'findBy',
'params' => array(
'criteria' => array('parent' => null),
),
),
),
)
);
}
}
select在表单中的水合起作用,因为它仅显示没有父母的其他角色。但是,在编辑现有实体时,它会在选择中显示自己,因此我可以选择自己作为父母。我认为,如果我可以在表单中具有当前实体的ID,则可以使用一个方法来创建一个自定义存储库,该方法可以在没有父母的情况下检索所有角色,并且没有当前的实体ID。但是我无法弄清楚如何从表单内部获得当前编辑的实体的ID。
任何帮助都将不胜感激。
欢呼,
yrm
您可以使用 $this->getObject()
。
您实际上已经使用setObject(new Role());
设置了此设置。不幸的是,这意味着它没有通过Doctine加载,您将遇到同样的问题,没有$id
可以使用。
因此,您需要在之后添加"父角色"选项(value_options
)您已通过Doctrine 限制了加载的角色。
从控制器内部,我通常从服务类请求"编辑"表单,然后传递正在编辑的实体实例或ID。一旦设置,您就可以在将现有元素传递回控制器之前修改现有元素。
// Controller
class RoleController
{
public function editAction()
{
$id = $this->params('id'); // assumed id passed as param
$service = $this->getRoleService();
$form = $service->getRoleEditForm($id); // Pass the id into the getter
// rest of the controller...
}
}
通过传递$id
,当您获取表单时,您可以在服务中修改该特定角色的表单元素。
class RoleService implements ObjectManagerAwareInterface, ServiceLocatorAwareInterface
{
protected function loadParentRolesWithoutThisRole(Role $role);
public function getRoleEditForm($id)
{
$form = $this->getServiceLocator()->get('RoleFormRoleEditForm');
if ($id) {
$role = $this->getObjectManager()->find('Role', $id);
$form->bind($role); // calls $form->setObject() internally
// Now the correct entity is attached to the form
// Load the roles excluding the current
$roles = $this->loadParentRolesWithoutThisRole($role);
// Find the parent select element and set the options
$form->get('parent')->setValueOptions($roles);
}
// Pass form back to the controller
return $form;
}
}
通过加载表格初始化后的选项,您不需要当前的DoctrineModuleFormElementObjectSelect
。未定义的没有默认value_options
的普通选择元素应该很好。