我有2个学说实体(Environment
和EnvironmentConfig
)。他们有bi-directional OneToOne的关系。学说OneToOne双向和单向ZF2 Fieldsets not saving/hydrating
每个实体都有自己的Fieldset,因此重复使用很容易。
要创建一个Environment
它也可以有一个EnvironmentConfig
,但不是必需的。为了让他们在同一时间,我有一个EnvironmentForm
使用EnvironmentFieldset
和EnvironmentConfigFieldset
。
窗体呈现正确。但是,它节省了Environment
但不是EnvironmentConfig
。
它在哪里出错了,如何解决这个问题?
下面的代码,遗漏了getter/setters,会太多了。
实体
// abstract class AbstractEntity has $id + getters/setters.
class Environment extends AbstractEntity
{
/**
* @var string
* @ORM\Column(name="name", type="string", length=255, nullable=false)
*/
protected $name;
/**
* @var EnvironmentConfig
* @ORM\OneToOne(targetEntity="Environment\Entity\EnvironmentConfig", inversedBy="environment")
*/
protected $config;
/**
* @var EnvironmentScript
* @ORM\OneToOne(targetEntity="EnvironmentScript")
*/
protected $script;
//Getters/setters
}
class EnvironmentConfig extends AbstractEntity
{
/**
* @var string
* @ORM\Column(name="name", type="string", length=255, nullable=false)
*/
protected $name;
/**
* @var Environment
* @ORM\OneToOne(targetEntity="Environment\Entity\Environment", mappedBy="config")
*/
protected $environment;
//Getters/setters
}
字段集
class EnvironmentFieldset extends AbstractFieldset
{
/**
* {@inheritdoc}
*/
public function init()
{
//Loads id element validation
parent::init();
$this->add([
'name' => 'name',
'type' => Text::class,
'options' => [
'label' => _('Name'),
'label_attributes' => [
'class' => 'col-xs-2 col-form-label',
],
],
'attributes' => [
'id' => 'name',
'class' => 'form-control'
],
]);
$this->add([
'name' => 'environment_config',
'type' => EnvironmentConfigFieldset::class,
'options' => [
'use_as_base_fieldset' => false,
],
]);
$this->add([
'type' => ObjectSelect::class,
'name' => 'environment_script',
'options' => [
'object_manager' => $this->getEntityManager(),
'target_class' => EnvironmentScript::class,
'property' => 'id',
'display_empty_item' => true,
'empty_item_label' => '---',
'label_generator' => function ($targetEntity) {
return $targetEntity->getId() . ' - ' . $targetEntity->getName();
},
],
]);
}
}
class EnvironmentConfigFieldset extends AbstractFieldset
{
/**
* {@inheritdoc}
*/
public function init()
{
//Loads id element validation
parent::init();
$this->add([
'name' => 'name',
'type' => Text::class,
'options' => [
'label' => _('Name'),
'label_attributes' => [
'class' => 'col-xs-2 col-form-label',
],
],
'attributes' => [
'id' => 'name',
'class' => 'form-control'
],
]);
}
}
表
class EnvironmentForm extends AbstractForm
{
/**
* EnvironmentForm constructor.
* @param null $name
* @param array $options
*/
public function __construct($name = null, array $options)
{
//Also adds CSRF
parent::__construct($name, $options);
}
/**
* {@inheritdoc}
*/
public function init()
{
//Call parent initializer. Adds submit button.
parent::init();
$this->add([
'name' => 'environment',
'type' => EnvironmentFieldset::class,
'options' => [
'use_as_base_fieldset' => true,
],
]);
}
}
以上在下面的功能persist()
线进行调试。
public function addAction($formName, array $formOptions = null, $route, array $routeParams = [])
{
if (!$this->formElementManager instanceof FormElementManagerV2Polyfill) {
throw new InvalidArgumentException('Dependency FormElementManagerV2Polyfill not set. Please check Factory for this function.');
}
if (!class_exists($formName)) {
throw new ClassNotFoundException('Given class could not be found. Does it exist?');
}
/** @var AbstractForm $form */
$form = $this->getFormElementManager()->get($formName, (is_null($formOptions) ? [] : $formOptions));
/** @var Request $request */
$request = $this->getRequest();
if ($request->isPost()) {
$form->setData($request->getPost());
if ($form->isValid()) {
$entity = $form->getObject();
$this->getEntityService()->getEntityManager()->persist($entity);
$this->getEntityService()->getEntityManager()->flush();
$this->flashMessenger()->addSuccessMessage(
_('Successfully created object.')
);
$this->redirectToRoute($route, $this->getRouteParams($entity, $routeParams));
}
}
return [
'form' => $form,
'validationMessages' => $form->getMessages() ?: '',
];
}
阿超的感谢!关于这个答案的最糟糕的事情是:我以前总是这样做,所以这从来都不是问题,我自动而且已经被遗忘了。感谢提醒,现在跺脚忘了基本的教条:(;) – Nukeface