在Symfony项目上,使用Twig进行模板,我想知道如何以一组形式元素控制子场的渲染,同时仍然利用Symfony的优势"合同"功能。
由于业务要求,某些元素必须作为一组保持在一起,每行多个输入,并且用户能够根据需要添加或删除行。
实体对象包含:
protected $jobInfo = array(array("jobType" => "", "shift" => ""));
,形式对象包含:
public function buildForm(FormBuilderInterface $fb, array $options)
{
//...
$fb->add('jobInfo', CollectionType::class, array(
'required' => false,
'entry_type' => JobSetType::class,
// ...
'label' => "bla bla"));
子形式JobSetType
仅具有ChoiceType::class
的两个输入。现在,如果我在树枝文件中这样的模板:
{# ... #}
<tr><th>
{{ form_label(form.jobInfo) }}
</th><td>
{{ form_widget(form.jobInfo) }}
{{ form_errors(form.jobInfo) }}
</td></tr>
{# ... #}
...然后,它的"起作用"是从数据中有多少或更少的行,而用户可以添加或删除(使用我的JavaScript(。但是,该单元格的内容是Divs的混乱,它看起来像是页面上的一团糟,并且行上的默认标签为" 0"," 1",...,它们看起来像用户一样混乱。
我发现格式化子场的唯一方法是用索引来指代它们,例如:
<table><tr><th colspan="3">
{{ form_label(form.jobInfo) }}
</th></tr>
{# begin unit intended to repeat #}
<tr><th>
{{ form_label(form.jobInfo.0.jobType) }}
</th><th>
{{ form_label(form.jobInfo.0.shift) }}
</th></tr>
<tr><td>
{{ form_widget(form.jobInfo.0.jobType) }}
{{ form_errors(form.jobInfo.0.jobType) }}
</td><td>
{{ form_widget(form.jobInfo.0.shift) }}
{{ form_errors(form.jobInfo.0.shift) }}
</td></tr>
{# end unit intended to repeat #}
</table>
{{ include('addrow.html.twig', { 'whichRow': 'Another Job' }) }}
但是,现在,使用硬编码索引杀死了扩展和合同的事物,显然必须通过某些其他方式模拟,没收有用的Symfony功能。
另一个问题(Symfony Twig如何将类添加到表格行(发现可以通过更改DIV的使用来通过更改表单元素的主模板来更改,但是我不希望整个项目更改,只是在需要的情况下进行特定的模板。
在这种情况下,如何控制子元素的一个控制渲染,而无需使用硬编码索引(或以其他方式获得相同的结果(?
编辑:谢谢Lordrhodos,我以前尝试过这样的尝试:
form_widget(form.jobInfo.{{ loop.index0 }}.shift)
和
form_widget(form.jobInfo.{{ loop.index }}.shift)
每个都有语法错误。我的新理论,翻转列和行。
解决了我自己的问题。它只需要一个在树枝中的循环:
<table>
<tr><th>
{{ form_label(form.jobInfo.0.jobType) }}
</th><th>
{{ form_label(form.jobInfo.0.shift) }}
</th></tr>
{% for x in form.jobInfo %}
<tr><td>
{{ form_widget(x.jobType) }}
{{ form_errors(x.jobType) }}
</td><td>
{{ form_widget(x.shift) }}
{{ form_errors(x.shift) }}
</td></tr>
{% endfor %}
</table>