Symfony2在一个模板中有多个表单

时间:2012-12-21 13:00:06

标签: forms symfony twig

我的应用包含可以拥有多个设备的区域。

查看区域时,需要显示区域中每个设备的控件。

每个设备都是完全独立的,因此将Zone表单嵌入到Zone表单中似乎是不必要的 - 我只想一次处理对一个设备的更改。

目前我正在为每个设备创建一个表单并将它们传递给区域视图模板:

public function viewAction($zone_id)
{
    $zone = $this->getZoneById($zone_id);
    $forms = array();

    foreach ($zone->getDevices() as $device) {
        $forms[] = $this->createForm(new DeviceType(), $device)->createView();
    }

    return $this->render('AcmeBundle:Zones:view.html.twig', array('zone' => $zone, 'deviceForms' => $forms));
}

然后在视图模板中,我循环遍历表单:

{% for form in deviceForms %}
    {% include 'AcmeBundle:Devices:control.html.twig'
        with {'zone':zone, 'form':form}
    %}
{% endfor %}

这似乎工作正常,但我真的需要根据Device的'type'更改呈现的模板。最干净的方法是什么?我可以这样做:

{% if form.vars.data.type == 'foo' %}
    {% include 'AcmeBundle:Devices:control-foo.html.twig'
        with {'zone':zone, 'form':form}
    %}
{% elseif form.vars.data.type == 'bar' %}
    {% include 'AcmeBundle:Devices:control-bar.html.twig'
        with {'zone':zone, 'form':form}
    %}
{% endif %}

但这似乎在模板中加入太多逻辑?最好将模板分配给表单对象以某种方式呈现,但我不知道这是否可行?

1 个答案:

答案 0 :(得分:3)

您必须通过控制器在FormType中添加选项'template'或其他内容, 在FormType中,您必须声明默认选项'template'并将其传递给表单视图。

public function viewAction($zone_id)
{
    $zone = $this->getZoneById($zone_id);
    $forms = array();
    //You define a config for each type of device (you should use parameters)
    $templates = array(
        'foo' => 'AcmeBundle:Devices:control-foo.html.twig',
        'bar' => 'AcmeBundle:Devices:control-bar.html.twig',
    );
    foreach ($zone->getDevices() as $device) {
            //define your template here.
            $type = $device->getType();
            //add a template option in the form.
            $options['template'] == $templates[$type];
            $forms[] = $this->createForm(new DeviceType(), $device, $options)->createView();
    }

    return $this->render('AcmeBundle:Zones:view.html.twig', array('zone' => $zone, 'deviceForms' => $forms));
}

现在在DeviceType中你应该在表单中设置默认选项,它们将与我们在控制器中创建的选项合并。

public function getDefaultOptions(array $options) {

    return array(
        //...other options...

        //this is the default template of this form
        'template' => 'AcmeBundle:Devices:control.html.twig'
    );
}

然后在Builder

中设置表单上的属性
public function buildForm(FormBuilder $builder, array $options)
{
    $builder->setAttribute('template', $options['template']);
    //...your fields here...
}

最后,在视图中设置var模板。

public function buildView(FormView $view, FormInterface $form)
{   
    $view->set('template', $form->getAttribute('template'));
}

现在您可以阅读树枝中的“模板”选项,并包含相应的模板

{% for form in deviceForms %}
    {% include form.get('template') with {'zone':zone, 'form':form} %}
{% endfor %}

不要忘记在FormType

的开头添加行
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormBuilder;
相关问题