简体   繁体   English

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

[英]Symfony2 multiple forms in one template

My app consists of Zones that can have many Devices. 我的应用程序包含可以拥有许多设备的区域。

When viewing a Zone, it needs to display a control for each Device in the Zone. 查看区域时,需要显示区域中每个设备的控件。

Each Device is completely independent, so embedding the Device forms in a Zone form seems unnecessary - I only want to deal with changes to one device at a time. 每个设备都是完全独立的,因此将Zone表单嵌入到Zone表单中似乎是不必要的 - 我只想一次处理一个设备的更改。

Currently I'm creating a form for each device and passing them to the Zone view template: 目前我正在为每个设备创建一个表单并将它们传递给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));
}

And then in the view template, I'm looping through the forms: 然后在视图模板中,我循环遍历表单:

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

This seems to be working ok, but I really need to change the template that renders based on the 'type' of Device. 这似乎工作正常,但我真的需要根据设备的“类型”更改渲染的模板。 What's the cleanest way to do this? 最干净的方法是什么? I can do something like: 我可以这样做:

{% 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 %}

but this seems like putting too much logic in the template? 但这似乎在模板中加入太多逻辑? It would be better to assign the template to render to the form object somehow, but I've no idea if this is possible? 最好将模板分配给表单对象以某种方式呈现,但我不知道这是否可行?

You must add an option 'template' or whatever in the FormType via the controller, In the FormType you must declare the default option 'template' and pass it the the form view. 您必须通过控制器在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));
}

Now in the DeviceType you should set the defaults options in the form, they will be merged with options we create in the controller. 现在,在DeviceType中,您应该在表单中设置默认选项,它们将与我们在控制器中创建的选项合并。

public function getDefaultOptions(array $options) {

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

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

Then set the attribute on the form in the Builder 然后在Builder中的表单上设置属性

public function buildForm(FormBuilder $builder, array $options)
{
    $builder->setAttribute('template', $options['template']);
    //...your fields here...
}

And finally, set the var template in the view. 最后,在视图中设置var模板。

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

Now you can read the "template" option in twig, and include the corresponding template 现在,您可以阅读twig中的“模板”选项,并包含相应的模板

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

Do not forget to add lines at the beginning of the FormType 不要忘记在FormType的开头添加行

use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormBuilder;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM