4

Zend-Framework 2 の Form-Component のチュートリアル/リファレンスを読みましたが、何らかの形で見逃したので、ここで質問しています。

というオブジェクトを取得し、Nodeそれをフォームにバインドしました。Zend\Stdlib\Hydrator\ArraySerializable-Standard-Hydratorを使用しています。したがって、私のNode-object には、次のような と の 2 つのメソッドが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自分のフォームのメソッドを使用しています。node_name私のフォームには、とプロパティを変更するためのフィールドしかありませんnode_body。フォームを検証し、フォームの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他の値は上書きしたくありません。それらはそのままにしておく必要があります。

可能な解決策は、他のプロパティを隠しフィールドとしてフォームに与えることだと思いますが、これはしたくありません。

フォーム内に存在しない値を上書きしない可能性はありますか?

4

4 に答える 4

3

\Zend\Form のコードを再確認しましたが、正直に言うと、問題を解決する方法を推測しただけです。

変えたのはハイドレーターだけです。Zend\Stdlib\Hydrator\ArraySerializable私の場合は意図されていないようです。私のNode-Object はオブジェクトであり、配列ではないため、他の利用可能なハイドレーターをチェックしました。ハイドレーターを見つけましたZend\Stdlib\Hydrator\ObjectProperty。それは完全に機能します。フォーム内で使用可能なフィールドのみが、バインドされたオブジェクト内に取り込まれます。これはまさに私が必要とするものです。ArraySerializable-hydratorexchangeArrayは、バインドされたオブジェクトの -method を呼び出すため、オブジェクトのプロパティをリセットするようです ( ) Node。そして、このメソッドでは、指定されていないフィールドをに設定していますnull(私の質問のコードを参照してください)。別の方法は、おそらくexchangeArray-method を変更して、値がまだ利用できない場合にのみ値を設定することです。

したがって、コード内のソリューションは簡単です。

$form = $this->_getForm();
$form->setHydrator(new \Zend\Stdlib\Hydrator\ObjectProperty()); // Change default hydrator
于 2012-12-26T22:21:24.387 に答える
2

クラス form.php にバグがあります。フィルタは bindvalues メソッドで初期化されず、$filter->setData($this->data);という行を追加するだけです。

行を含めた後、次のようになります

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行目です

これで問題が解決します。これは、バインドされたオブジェクトの状況でのみ発生します

于 2012-12-26T09:10:20.977 に答える
1

私は同じ問題に遭遇しましたが、Raj の解決策は正しい方法ではありません。これはバグではありません。今日のコードは、Raj の「修正」がなくても同様のままであり、次の行を追加します。

$filter->setData($this->data);

ここでの主な問題は、オブジェクトをフォームにバインドするときに、inputfilter が Form オブジェクト内に格納されないことです。ただし、バインドされたオブジェクトから毎回呼び出されます。

public function getInputFilter()
    ...
    $this->object->getInputFilter();
    ...
}

私の問題は、関数 getInputFilter が呼び出されるたびに新しい InputFilter オブジェクトを作成することでした。そこで、以下のように修正しました。

protected $filter;
...
public function getInputFilter {
    if (!isset($this->filter)) {
        $this->filter = new InputFilter();
        ...
    }
    return $this->filter;
}
于 2015-02-09T15:38:47.043 に答える