我已经通读了Zend-Framework2中的表单组件的教程/参考,也许我错过了它,所以我在这里提问。
我有一个名为Node的对象,并将其绑定到一个表单。我用的是Zend\Stdlib\Hydrator\ArraySerializable标准饮水机。所以我的Node-object有exchangeArray()和getArrayCopy()的两个方法,如下所示:
class Node
{
public function exchangeArray($data)
{
// Standard-Felder
$this->node_id = (isset($data['node_id'])) ? $data['node_id'] : null;
$this->node_name = (isset($data['node_name'])) ? $data['node_name'] : null;
$this->node_body = (isset($data['node_body'])) ? $data['node_body'] : null;
$this->node_date = (isset($data['node_date'])) ? $data['node_date'] : null;
$this->node_image = (isset($data['node_image'])) ? $data['node_image'] : null;
$this->node_public = (isset($data['node_public'])) ? $data['node_public'] : null;
$this->node_type = (isset($data['node_type'])) ? $data['node_type']:null;
$this->node_route = (isset($data['node_route'])) ? $data['node_route']:null;
}
public function getArrayCopy()
{
return get_object_vars($this);
}
}在我的控制器中,我有一个editAction()。在这里,我想修改这个Node-object的值。因此,我使用的是表单的bind-method。我的表单只有用于修改node_name和node_body-property的字段。在验证表单并在提交表单后转储Node-object之后,node_name和node_body-properties现在包含来自提交的表单的值。然而,所有其他字段现在都是空的,即使它们以前包含初始值。
class AdminController extends AbstractActionController
{
public function editAction()
{
// ... more stuff here (getting Node, etc)
// Get Form
$form = $this->_getForm(); // return a \Zend\Form instance
$form->bind($node); // This is the Node-Object; It contains values for every property
if(true === $this->request->isPost())
{
$data = $this->request->getPost();
$form->setData($data);
// Check if form is valid
if(true === $form->isValid())
{
// Dumping here....
// Here the Node-object only contains values for node_name and node_body all other properties are empty
echo'<pre>';print_r($node);echo'</pre>';exit;
}
}
// View
return array(
'form' => $form,
'node' => $node,
'nodetype' => $nodetype
);
}
}我只想覆盖来自表单(node_name和node_body)的值,而不是其他值。它们应该保持原样。
我认为一个可能的解决方案是将其他属性作为隐藏字段添加到表单中,但我不想这样做。
有没有可能不覆盖表单中不存在的值?
发布于 2012-12-27 06:21:24
我重新检查了\Zend\Form的代码,老实说,我只是猜测如何解决我的问题。
我唯一改变的就是饮水机。似乎Zend\Stdlib\Hydrator\ArraySerializable不是为我的情况而设计的。因为我的Node-Object是一个对象而不是数组,所以我检查了其他可用的other。我找到Zend\Stdlib\Hydrator\ObjectProperty-hydrator了。它工作得很完美。只有表单中可用的字段才会填充到绑定对象中。这正是我需要的。看起来像是ArraySerializable-hydrator重置了对象属性,因为它调用了绑定对象的exchangeArray-method (Node)。在此方法中,我将未给定的字段设置为null (请参阅我问题中的代码)。另一种方法可能是更改exchangeArray-method,以便仅在值还不可用时才设置这些值。
因此,代码中的解决方案很简单:
$form = $this->_getForm();
$form->setHydrator(new \Zend\Stdlib\Hydrator\ObjectProperty()); // Change default hydrator发布于 2012-12-26 17:10:21
bindvalues类中存在错误,只需添加行$filter->setData($this->data);即可在form.php方法中不初始化筛选器
在包含下面这行之后,它应该如下所示
public function bindValues(array $values = array())
{
if (!is_object($this->object)) {
return;
}
if (!$this->hasValidated() && !empty($values)) {
$this->setData($values);
if (!$this->isValid()) {
return;
}
} elseif (!$this->isValid) {
return;
}
$filter = $this->getInputFilter();
$filter->setData($this->data); //added to fix binding empty data
switch ($this->bindAs) {
case FormInterface::VALUES_RAW:
$data = $filter->getRawValues();
break;
case FormInterface::VALUES_NORMALIZED:
default:
$data = $filter->getValues();
break;
}
$data = $this->prepareBindData($data, $this->data);
// If there is a base fieldset, only hydrate beginning from the base fieldset
if ($this->baseFieldset !== null) {
$data = $data[$this->baseFieldset->getName()];
$this->object = $this->baseFieldset->bindValues($data);
} else {
$this->object = parent::bindValues($data);
}
}更重要的是,它在我的zf2.0.6库中是第282行
这将解决您的问题,这只在绑定对象的情况下发生
发布于 2015-02-09 23:38:47
我遇到了同样的问题,但Raj的解决方案不是正确的方法。这不是一个bug,因为今天的代码在没有Raj的“修复”的情况下仍然保持相似,添加了一行:
$filter->setData($this->data);这里的主要问题是,当您将对象绑定到表单时,inputfilter不会存储在表单对象中。而是每次从绑定的对象中调用。
public function getInputFilter()
...
$this->object->getInputFilter();
...
}我的问题是每次调用getInputFilter函数时都会创建一个新的InputFilter对象。因此,我将其更正为如下内容:
protected $filter;
...
public function getInputFilter {
if (!isset($this->filter)) {
$this->filter = new InputFilter();
...
}
return $this->filter;
}https://stackoverflow.com/questions/14029821
复制相似问题