Forms Symfony2:优化表单集合
在Symfony2应用程序的控制器中,我使用元素集合。元素越多,花费的时间就越多。这听起来合乎逻辑,但似乎有反复的叛逆:Forms Symfony2:优化表单集合,forms,performance,symfony,collections,Forms,Performance,Symfony,Collections,在Symfony2应用程序的控制器中,我使用元素集合。元素越多,花费的时间就越多。这听起来合乎逻辑,但似乎有反复的叛逆: 我从MyCollectionType创建了一个表单 在buildForm方法中,我添加了具有自己的buildForm方法的ElementType 然后,当Symfony2使用我传递的元素列表构建表单时,将为每个元素调用ElementType的buildForm方法一次 =>是否不可能先生成第一个ELementType,然后克隆其他ELementType 我不明白为什么这些
- 我从MyCollectionType创建了一个表单
- 在buildForm方法中,我添加了具有自己的buildForm方法的ElementType
这是因为表单的处理方式,还是可以优化表单?答案很简单:你应该优化你的编程技能,而不是symfony表单。这是你关于同一问题的下一个问题
您希望在每个输入周围使用字段集和/或div渲染4200多个字段,因此我怀疑30秒是它在浏览器中渲染的时间。我为我的一个应用程序添加了相同的问题,我所做的是重新实现了一个基本表单类原型,方法名称与Symfony2几乎相同,并以最简单的方式重新实现,如下所示:
在Twig模板中,我只是迭代数据以创建表单字段、重新填充值并显示错误。表单相同,但生成时间为100ms,而不是30秒。。。对于所有其他表格,我一直使用Symfony2表格。30是从哪里来的?Symfony或browser?最近出现了不少这样的“巨大形式”问题。归根结底,Symfony表单的设计是为了支持合理数量的元素。表单经过高度设计,开销很大。如果你真的坚持让你的用户使用包含700个输入元素的表单,那么你可能需要一种不同的方法。为了回答你的评论,有很棒的JS库可以在很短的时间内(在现代浏览器中)显示巨大的表liek DataTable。@Rolintocour-是的,因为它们只有在被请求时才使用ajax调用显示,或者我错了,你向我展示了一个有几千个输入字段的神奇页面?一个350行的表格,每行大约有5个输入,使用jquery.html()在IE11或Firefox中5秒钟内显示。当我在客户端模式下使用DataTable时(ia),我插入该表,但立即将.DataTable()应用于该表,它将显示为无delay@Rolintocour-当然,你想告诉我用js插入html比纯html更快吗?我认为插入要显示的巨大html很慢;但是插入巨大的HTML并立即隐藏其中的一部分(在渲染完成之前)速度很快,而且可能会被浏览器优化。这样,我测试了插入整个HTML(350行),立即隐藏所有TR,然后只显示50个first=>这很快
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';
}
}