Symfony2具有多个字段的窗体自定义字段类型


Symfony2 Form custom field type with more than 1 field

与Symfony2表单作斗争。User对象具有Location类的属性。表单需要在两个选择框中显示位置:国家、城市。(稍后将通过ajax更新城市选择框)。

尝试使用数据转换器和事件,但找不到出路,只是变得更加困惑。有没有任何关于采取哪些步骤来实现这一目标的提示?

// User class
class User
{
     ...
     protected $location;
}    
// LOCATION class
class Location
{
        ...
        protected $city;
        protected $country;
}

// User TYPE
class UserType extends AbstractType
{
    ...
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        ...
        $builder->add("location", new LocationType);
    }
}
// CUSTOM Location FORM TYPE
class LocationType extends AbstractType
{
....
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add("country", "choice");
        $builder->add("city", "choice");

    }
}

在阅读了一天的文档后,我发现了Bernhard Schussek的一段非常有用的视频。http://www.youtube.com/watch?v=Q80b9XeLUEA

看了两遍之后,才知道如何满足这个要求。

  • 模型数据的类型为Location
  • 标准化数据属于阵列类型

  • 制作了一个数据转换器,将Location对象转换为数组,其中键对应于自定义字段类型(国家、城市)中的字段名。

数据转换器应用于整个自定义类型对象:

$builder->addModelTransformer(new LocationToArrayTransformer());
  • 在buildForm中添加并预填充country字段
  • 在PRE_SET_DATA上触发的事件侦听器中添加并预填充城市字段。它还检查国家的价值,并在此基础上预先填充城市:

    $builder->addEventListener(''Symfony''Component''Form''FormEvents::PRE_SET_DATA,函数(FormEvent$event){

     $cities = array(); // prepopulate here using a service, etc.
     $event->getForm()->add("cityId", "choice", array("choices" => $cities));
    

    });

  • 使用jQuery添加了使用ajax动态更新城市选择的功能。