【问题标题】:Populating Form Data in ZF2 when using Fieldsets使用字段集时在 ZF2 中填充表单数据
【发布时间】:2012-06-08 00:24:25
【问题描述】:

我目前正在使用 ZF2 beta 4,当我尝试在表单中使用字段集并在提交表单时将数据返回到表单中时,我似乎被卡住了。我不确定我是否没有为字段集设置正确的输入过滤器,或者我遗漏了一些东西。例如,我有以下内容(简化为清楚):

控制器

public function indexAction(){
   $form = new MyForm();
   $request = $this->getRequest();
          if ($request->isPost()) {
                 $form->setData($request->post());
                 if ($form->isValid()) {
                        //Do something
                        print_r($form->getData()); //for debug
                 }
          }
   return array('form' => $form);
}

MyForm.php

class MyForm extends Form
{
    public function __construct()
    {
        parent::__construct();
        $this->setName('myForm');
        $this->setAttribute('method', 'post');

        $this->add(array(
                    'name' => 'title',
                    'attributes' => array(
                    'type'  => 'text',
                    'label' => 'Title',
                    ),
                 ));

        $this->add(new MyFieldset('myfieldset'));

        //setting InputFilters here
        $inputFilter = new InputFilter();
        $factory = new InputFactory();

        $inputFilter->add($factory->createInput(array(
            'name'     => 'title',
            'required' => true,
            'filters'  => array(
                array('name' => 'StripTags'),
                array('name' => 'StringTrim'),
            ),
        )));

        //Now add fieldset Input filter
        foreach($this->getFieldsets() as $fieldset){
              $fieldsetInputFilter = $factory->createInputFilter($fieldset->getInputFilterSpecification());
              $inputFilter->add($fieldsetInputFilter,$fieldset->getName());
        }

        //Set InputFilter
        $this->setInputFilter($inputFilter);
    }
}

MyFieldset.php

class MyFieldset extends Fieldset implements InputFilterProviderInterface{
    public function __construct($name)
    {
        parent::__construct($name);
        $factory = new Factory();

        $this->add($factory->createElement(array(
            'name' => $name . 'foo',
            'attributes' => array(
                'type'  => 'text',
                'label' => 'Foo',
            ),
        )));
    }

    public function getInputFilterSpecification(){
        return array(
            'foo' => array(
                'required' => true,
                'filters'  => array(
                    array('name' => 'StripTags'),
                    array('name' => 'StringTrim'),
                ),
            ),
        );
    }
}

我能够按预期输出表单,并最终得到两个输入元素,名为“title”和“myfieldsetfoo”(使用 ViewHelper 输出时给出的名称)。因此,当我提交原始帖子时,当然会显示“title”和“myfieldsetfoo”的值。但是,当我使用 SetData() 时,不会填充字段集的值(尽管我可以看到原始帖子对象中的值)。相反,检查我收到的 '$form->getData()' 的输出:

Array(
   [title] => Test,
   [myfieldset] => Array(
                         [foo] =>
                        )
)

我错过了什么?我需要做什么才能让 ZF2 了解如何填充字段集?

感谢您的帮助,这让我发疯了。

【问题讨论】:

    标签: zend-form zend-framework2


    【解决方案1】:

    我这样做的原因是连接 InputFilter,这样我就可以处理发布的整个 HTML 表单数组。

    <form method="POST">
    <input type="text" name="main[name]" />
    <input type="text" name="main[location]" />
    <input type="text" name="contact[telephone]" />
    
    <input type="submit" value="Send" />
    </form>
    

    这将创建一个像这样发布的数组

    post["main"]["name"]
    post["main"]["location"]
    post["contact"]["telephone"]
    

    过滤和验证:

    use Zend\InputFilter\InputFilter;
    use Zend\InputFilter\Factory as InputFactory;
    
    $post = $this->request->getPost();
    $inputFilter = new InputFilter();
    $factory = new InputFactory();
    
    // $post["main"]
    $mainFilter = new InputFilter();
    $mainFilter->add($factory->createInput(array(
        'name'     => 'name',
        'required' => true,
        'filters'  => array(
            array('name' => 'StripTags'),
            array('name' => 'StringTrim'),
        ),
        'validators' => array(
            array(
                'name'    => 'StringLength',
                'options' => array(
                    'encoding' => 'UTF-8',
                    'min'      => 1,
                    'max'      => 100,
                ),
            ),
        ),
        )));
    
    $mainFilter->add($factory->createInput(array(
        'name'     => 'location',
        'required' => true,
        'filters'  => array(
            array('name' => 'StripTags'),
            array('name' => 'StringTrim'),
        ),
        'validators' => array(
            array(
                'name'    => 'StringLength',
                'options' => array(
                    'encoding' => 'UTF-8',
                    'min'      => 1,
                    'max'      => 100,
                ),
            ),
        ),
        )));
    $inputFilter->add($mainFilter, "main");
    
    // $post["contact"]
    $contactFilter = new InputFilter();
    $contactFilter->add($factory->createInput(array(
        'name'     => 'name',
        'required' => true,
        'filters'  => array(
            array('name' => 'StripTags'),
            array('name' => 'StringTrim'),
        ),
        'validators' => array(
            array(
                'name'    => 'StringLength',
                'options' => array(
                    'encoding' => 'UTF-8',
                    'min'      => 1,
                    'max'      => 100,
                ),
            ),
        ),
        )));
    $contactFilter->add($mainFilter, "contact");
    
    //Set posted data to InputFilter
    $inputFilter->setData($post->toArray());
    

    http://www.unexpectedit.com/zf2/inputfilter-validate-and-filter-a-form-data-with-fieldsets

    【讨论】:

    • +1 表示此行 $contactFilter-&gt;add($mainFilter, "contact");。现在我知道如何为字段集应用过滤器。谢谢!
    【解决方案2】:

    我想你忘记在控制器中准备表单了:

    return array('form' => $form->prepare());
    

    这会将您的字段集的“名称”字段重命名为“myfieldset [foo]”,因此您不必自己添加字段集名称。

    随便用

    'name' => 'foo'
    

    而不是

    'name' => $name . 'foo'
    

    在您的字段集类中。

    【讨论】:

      【解决方案3】:

      我认为问题在于您在控制器中声明了一个新表单。这样就清除了之前的表格。

      $form = new MyForm();
      

      我使用 Service Manager 来声明表单和过滤器。 然后在控制器中我这样做:

      $form = $this->getServiceLocator()->get('my_form');
      

      这样我总能得到我想要的对象

      更新

      我不再使用服务管理器来调用表单。我只是调用一个新表单并发出 $form->setData($data);

      数据的来源也可以是实体,但我会发出:$form->bind($entity)

      【讨论】:

      • 这种形式的声明方式与http://akrabat.com/zend-framework-2-tutorial/ 的做法类似。我只在使用字段集时才看到问题。如果我有一个简单的表单(甚至是不在字段集中的元素),我可以毫无问题地取回数据。
      • 实例化表单的方法与此问题完全无关。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-12
      • 2010-11-04
      相关资源
      最近更新 更多