0

在我当前的项目中,我使用了嵌套的Zend\Form\Fieldset s和Zend\Form\Collections,它们提供了一种非常舒适的方式将复杂的对象结构映射到表单,以便从表单输入中获取完整的对象(可以保存)。如何装饰ZF2集合中的字段集的元素?

的问题:我有一个FieldsetFooFieldset含有Elementfoo_elementLabel为“foo元件”(代码见下文),并且需要使用两次:1.作为单个Fieldset; 2.在Collection。在表单的第一位,我希望显示其元素;在第二个地方,我想禁用标签(或者可能改变它们)。 (我也想把它格式化在第二种情况中的另一种方式,但现在最重要的事情是标签。)

根据上下文如何装点Zend\Form\ElementZend\Form\Fieldset的在Zend\Form\Element\Collection


代码

class FooFieldset extends Fieldset implements InputFilterProviderInterface 
{ 
    public function init() 
    { 
     $this->add([ 
      'type' => 'text', 
      'name' => foo_element', 
      'options' => ['label' => _('foo element')] 
     ]); 
    } 
    public function getInputFilterSpecification() { ... } 
} 

class BarFieldset extends Fieldset implements InputFilterProviderInterface 
{ 
    public function init() 
    { 
     $this->add([ 
      'name' => 'foo', 
      'type' => 'My\Form\Fieldset\Foo', 
      'options' => [] 
     ]); 
    } 
    public function getInputFilterSpecification() { ... } 
} 

class BuzFieldset extends Fieldset implements InputFilterProviderInterface 
{ 
     $this->add(
      [ 
       'name' => 'foos', 
       'type' => 'Zend\Form\Element\Collection', 
       'options' => [ 
        'label' => _('multiple foos'), 
        'count' => 5, 
        'should_create_template' => true, 
        'template_placeholder' => '__placeholder__', 
        'allow_add' => true, 
        'target_element' => [ 
         'type' => 'Order\Form\Fieldset\Foo', 
        ], 
        'label_attributes' => [ 
         'class' => 'col-md-12' 
        ] 
       ] 
      ]); 
    public function getInputFilterSpecification() { ... } 
} 

echo $this->formRow($myForm->get('main_fieldset')->get('bar')->get('foo')->get('foo_element'); 
echo $this->formRow($myForm->get('main_fieldset')->get('buz')->get('foos'); 

解决方法1

这将有可能使用另一种Fieldset,例如一个FooFieldst(sometnig like FooFieldsetForUsingInCollection extends FooFieldst)的子类,并在那里调整Label(和其他设置)。

解决方法2

也将是可以访问在视图脚本CollectionElement秒和操纵它们在那里(如here证实)。但我不太喜欢这个解决方案,因为Fieldset被定义在多个地方。如果Collection元素的数量是可变的,那么还需要进一步的努力。

+0

'main_fieldset' ='BuzFieldset'? – AlexP

+0

不,'Bar'和'Buz'都是'MainFieldset'的Sub-'Fieldset'。对不起,这是一个错字。请参阅更正的代码。 – automatix

回答

0

看起来您需要在自己的字段集中重用'foos'集合和'bar'元素,同时保持当前创建的方式。

我会

  • 移动集合元素fooBuzFieldset::init,进入它自己的工厂(创建于工厂的元素和它所有的选项)。

  • 将表单元素管理器注册为新服务​​,可以将其称为FooCollection。这个元素现在可重用,可以从表单元素管理器调用$fem->get('FooCollection')

  • 替换删除$fieldset->add('type' => 'Zend\Form\Element\Collection')$fieldset->add('type' => 'FooCollection')BuzFieldset

  • 对于foo_element重复以新的服务名称FooElement

  • 然后,您需要创建一个名为FooCollectionAndFooElementFieldsetFactory的新字段集工厂,该工厂将返回一个新字段集,并附上FooCollectionFooElement

  • 工厂main_fieldset决定是否需要附加FooCollectionAndFooElementFieldsetFactory或现有barbaz字段集。

+0

非常感谢您的回答!虽然,这似乎有点太复杂。我认为,目前还没有针对这个问题的Zend解决方案。但是,如果我必须解决它,我会用这种方式:1.创建一个'FooForCollectionFieldsetFactory'; 2.在那里操作'FooFieldset'; 3.将'My \ Form \ Fieldset \ FooForCollection'=>'My \ Form \ Fieldset \ Factory \ FooForCollectionFieldsetFactory'添加到'module.config.php'中的'form_elements.factories'; 4.将'Collection'的'target_element.type'设置为''My \ Form \ Fieldset \ FooForCollection''。 – automatix