在Symfony2应用程序的控制器中,我使用了元素集合。元素越多,花费的时间就越多。这听起来合乎逻辑,但似乎有重复的特征:
然后当Symfony2使用我传递的元素列表构建表单时,为每个元素调用ElementType的buildForm方法
=>这是不可能建立第一个ELementType,然后克隆其他?
我不明白为什么这些子表单之间会有任何不同之处,唯一的区别就是设置数据而不是构建表单。
然后我注意到buildView方法的相同内容:每个元素都有很多重复处理,其中只有数据(可能是侦听器的处理)可能会有所不同。 例如,在我的应用程序中,ElementType有6个字段,700个元素的集合,渲染表单最多需要30秒。 是由于处理表单的方式还是可以优化的?
答案 0 :(得分:0)
我为我的一个应用程序添加了同样的问题,我所做的是我重新实现了一个基本的表单类原型,方法名称几乎与Symfony2相同,并以最简单的方式重新实现,它看起来像这样:
class SimpleForm
{
/**
* @var ContainerInterface $container Main application DIC
*/
protected $container;
/**
* @var array $options Options of the form
*/
protected $options = array();
/**
* @var array $options Raw datas for the form.
*/
protected $data = array();
/**
* @var array $options Data of the form against user input.
*/
protected $boundData = array();
/**
* @var array $errors List of errors after form valisation
*/
protected $errors = array();
/**
* @var array $options Tells if the datas were bound to the form.
*/
protected $isBound = false;
/**
* @var array $options Tells if the form validation is ok
*/
protected $isValid = false;
/**
* Main constructor.
*
* @param ContainerInterface $container The main DIC
* @param array $options Options of the form
*/
public function __construct(ContainerInterface $container, $options = array())
{
$this->container = $container;
$this->options = $options;
$this->buildForm();
}
/**
* Add widgets to the form.
*/
public function buildForm()
{
$this->widgets['keywordType'] = self::$keywordTypes;
}
/**
* @return array
*/
public function getOptions()
{
return $this->options;
}
/**
* @param array $options
*/
public function setOptions($options)
{
$this->options = $options;
}
/**
* @return string
*/
public function getEnctype()
{
return isset($this->options['enctype']) ? $this->options['enctype'] : '';
}
/**
* If the form is bound it return the bound datas, it returns the raws datas otherwise.
*
* @return array
*/
public function getData()
{
return $this->isBound ? $this->boundData : $this->data;
}
/**
* @throws \LogicException
*
* @return array
*/
public function getErrors()
{
if ($this->isBound == false) {
throw new \LogicException('The form must be bound before the errors can be retrieved');
}
return $this->errors;
}
/**
* @throws \LogicException
*
* @return array
*/
public function hasErrors()
{
if ($this->isBound == false) {
throw new \LogicException('The form must be bound before the errors can be checked');
}
return !empty($this->errors);
}
/**
* @throws \LogicException
*
* @return array
*/
public function getBoundData()
{
if ($this->isBound == false) {
throw new \LogicException('The form must be bound before getting the form final datas');
}
return $this->boundData;
}
/**
* @param array $data
*
* @return SimpleForm
*/
public function setData($data)
{
$this->data = $data;
return $this;
}
/**
* Bind the submitted values to the form.
*
* @param array $values The values to bind
*
* @return SimpleForm
*/
public function bind($values)
{
$values = $this->clean($values);
$this->boundData = Tools::arrayDeepMerge($this->data, $values);
$this->isBound = true;
$this->validate();
return $this;
}
/**
* Clean raw form values before the validation.
*
* @param array $values The raw values submitted by the user.
*
* @return array
*/
protected function clean($values)
{
// ...
return $values;
}
/**
* Run the validation against the form.
*
* @return boolean
*/
protected function validate()
{
$this->errors = array();
// ...
$this->isValid = empty($this->errors);
return $this->isValid;
}
/**
* Return the validation state of the form.
*
* @throws \LogicException
*
* @return boolean
*/
public function isValid()
{
if ($this->isBound == false) {
throw new \LogicException('The form must be bound before getting the validation status');
}
return $this->isValid;
}
/**
* Returns the datas that will be necesary for the view.
*
* @return array
*/
public function createView()
{
return array(
'widgets' => $this->widgets,
'options' => $this->options,
'data' => $this->boundData, // Don't forget to escape values against XSS
'enctype' => $this->getEnctype(),
'errors' => $this->errors,
'name' => $this->getName(),
);
}
/**
* @return string The name of the form
*/
public function getName()
{
return 'search';
}
}
在Twig模板中,我只是迭代数据以创建表单字段,重新填充值并显示错误。表单是相同的,但生成时间为100毫秒而不是30秒...对于我使用Symfony2的所有其他表单。
答案 1 :(得分:-2)
答案很简单:你应该优化你的编程技巧,而不是symfony表格。这是关于同一问题的下一个问题(很多)。
你想要在每个输入周围渲染超过4200个字段集和/或div的字段,所以我怀疑它是在浏览器中呈现的时间是30秒。