将自定义选项添加到 symfony 表单
Add custom options to symfony form
1 我想要做的是向我的表单小部件模板添加自定义选项(在本例中为 'angular')选项:
{%- block widget_attributes -%}
id="{{ id }}" name="{{ full_name }}"
{%- if angular %} ng-model="{{ full_name }}"{% endif -%}
....
{%- if intention %} {{ intention }}{% endif -%}
{%- if read_only %} readonly="readonly"{% endif -%}
.....
{%- endblock widget_attributes -%}
我想决定在我的 CustomFormType 中是否有表单选项。
但我无法实现它。我尝试了不同的方法。
是否可以在主窗体中添加自定义选项?
我知道有很多教程展示了如何在子元素中传递自定义选项,例如 http://symfony.com/doc/current/cookbook/form/create_form_type_extension.html
我调查了表单组件的核心,有class
namespace Symfony\Component\Form\Extension\Core\Type;
class FormType extends BaseType{}
它有方法 build View
public function buildView(FormView $view, FormInterface $form, array $options)
{
.....
$view->vars = array_replace($view->vars, array(
'read_only' => $readOnly,
'errors' => $form->getErrors(),
'valid' => $form->isSubmitted() ? $form->isValid() : true,
'value' => $form->getViewData(),
'data' => $form->getNormData(),
'required' => $form->isRequired(),
'max_length' => isset($options['attr']['maxlength']) ? $options['attr']['maxlength'] : null, // Deprecated
'pattern' => isset($options['attr']['pattern']) ? $options['attr']['pattern'] : null, // Deprecated
'size' => null,
'label_attr' => $options['label_attr'],
'compound' => $form->getConfig()->getCompound(),
'method' => $form->getConfig()->getMethod(),
'action' => $form->getConfig()->getAction(),
'submitted' => $form->isSubmitted(),
));
}
以上 symfony 定义基本选项。我可以在表单模板中全局访问这些选项,但我找不到添加自己的方法。
只需在表单类型中添加默认选项
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
// default form options
'my_options' => 'my default value option'
));
}
编辑
/**
* {@inheritdoc}
*/
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->vars['my_options'] = $options['my_options'];
}
我找到了基于@Charlie Lucas post 的解决方案。
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->vars['my_options'] = $options['my_options'];
}
以上方法仅更新父表单(我问过),但如果我在小部件模板中传递此选项:
{%- block widget_attributes -%}
{{ 'my_options' }}
{%- endblock widget_attributes -%}
我收到错误提示该选项不存在。
现在明白为什么会出错了。在每个小部件中调用此选项。这意味着子元素也会调用此选项。但是这个选项在children中没有定义。
为了解决这个问题,我在 FormType class 中为父表单和子表单添加了选项。
在
public function buildView(FormView $view, FormInterface $form, array $options)
{
.....
}
我们无权访问子元素,因此我不得不调用 finishView()。
在这种方法中,我使用递归函数向所有元素添加选项
public function finishView(FormView $view, FormInterface $form, array $options)
{
$params = array(
'angular'=>true,
);
$this->setParam( $view, $params);
}
private function setParam(FormView $view, array $params)
{
$this->updateParam($view, $params);
$this->updateChild($view, $params);
}
private function updateChild(FormView $parent, array $params)
{
foreach ($parent->children as $child){
$this->updateParam($child, $params);
$this->updateChild($child, $params);
}
}
private function updateParam(FormView $view, array $params)
{
foreach($params as $key => $value){
$view->vars[$key] = $value;
}
}
在 symfony 5 中
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'my_custom_option' => 'default_value',
'data_class' => User::class,
]);
}
1 我想要做的是向我的表单小部件模板添加自定义选项(在本例中为 'angular')选项:
{%- block widget_attributes -%}
id="{{ id }}" name="{{ full_name }}"
{%- if angular %} ng-model="{{ full_name }}"{% endif -%}
....
{%- if intention %} {{ intention }}{% endif -%}
{%- if read_only %} readonly="readonly"{% endif -%}
.....
{%- endblock widget_attributes -%}
我想决定在我的 CustomFormType 中是否有表单选项。 但我无法实现它。我尝试了不同的方法。
是否可以在主窗体中添加自定义选项?
我知道有很多教程展示了如何在子元素中传递自定义选项,例如 http://symfony.com/doc/current/cookbook/form/create_form_type_extension.html
我调查了表单组件的核心,有class
namespace Symfony\Component\Form\Extension\Core\Type;
class FormType extends BaseType{}
它有方法 build View
public function buildView(FormView $view, FormInterface $form, array $options)
{
.....
$view->vars = array_replace($view->vars, array(
'read_only' => $readOnly,
'errors' => $form->getErrors(),
'valid' => $form->isSubmitted() ? $form->isValid() : true,
'value' => $form->getViewData(),
'data' => $form->getNormData(),
'required' => $form->isRequired(),
'max_length' => isset($options['attr']['maxlength']) ? $options['attr']['maxlength'] : null, // Deprecated
'pattern' => isset($options['attr']['pattern']) ? $options['attr']['pattern'] : null, // Deprecated
'size' => null,
'label_attr' => $options['label_attr'],
'compound' => $form->getConfig()->getCompound(),
'method' => $form->getConfig()->getMethod(),
'action' => $form->getConfig()->getAction(),
'submitted' => $form->isSubmitted(),
));
}
以上 symfony 定义基本选项。我可以在表单模板中全局访问这些选项,但我找不到添加自己的方法。
只需在表单类型中添加默认选项
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
// default form options
'my_options' => 'my default value option'
));
}
编辑
/**
* {@inheritdoc}
*/
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->vars['my_options'] = $options['my_options'];
}
我找到了基于@Charlie Lucas post 的解决方案。
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->vars['my_options'] = $options['my_options'];
}
以上方法仅更新父表单(我问过),但如果我在小部件模板中传递此选项:
{%- block widget_attributes -%}
{{ 'my_options' }}
{%- endblock widget_attributes -%}
我收到错误提示该选项不存在。
现在明白为什么会出错了。在每个小部件中调用此选项。这意味着子元素也会调用此选项。但是这个选项在children中没有定义。
为了解决这个问题,我在 FormType class 中为父表单和子表单添加了选项。 在
public function buildView(FormView $view, FormInterface $form, array $options)
{
.....
}
我们无权访问子元素,因此我不得不调用 finishView()。 在这种方法中,我使用递归函数向所有元素添加选项
public function finishView(FormView $view, FormInterface $form, array $options)
{
$params = array(
'angular'=>true,
);
$this->setParam( $view, $params);
}
private function setParam(FormView $view, array $params)
{
$this->updateParam($view, $params);
$this->updateChild($view, $params);
}
private function updateChild(FormView $parent, array $params)
{
foreach ($parent->children as $child){
$this->updateParam($child, $params);
$this->updateChild($child, $params);
}
}
private function updateParam(FormView $view, array $params)
{
foreach($params as $key => $value){
$view->vars[$key] = $value;
}
}
在 symfony 5 中
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'my_custom_option' => 'default_value',
'data_class' => User::class,
]);
}