gpt4 book ai didi

forms - 以批量形式使用 Pagerfanta/非 ArrayAccess 列表

转载 作者:行者123 更新时间:2023-12-04 21:02:21 24 4
gpt4 key购买 nike

我正在使用提供的解决方案将批量操作的复选框添加到 CRUD 列表 here .

但是,我的结果是用 Pagerfanta 分页的,所以我似乎需要在我的表单中使用 DataMapper。

我尝试了各种解决方案,但无法在我的表单数据中获取所选字段:

class ModelEntitySelectionType extends AbstractType  implements DataMapperInterface
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('model_id', EntityType::class, [
'required' => false,
'class' => ModelFile::class,
'choice_label' => 'id',
'property_path' => '[id]', # in square brackets!
'multiple' => true,
'expanded' => true
])
->add('action', ChoiceType::class, [
'choices' => [
'Delete' => 'delete'
]
])
->add('submit', SubmitType::class, [
'label' => 'Process'
])

->setDataMapper($this)
;


}

public function setDefaultOptions(ExceptionInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => null,
'csrf_protection' => false
));
}

public function mapDataToForms($data, $forms)
{
// there is no data yet, so nothing to prepopulate
if (null === $data) {
return;
}

$formData = [];

/** @var FormInterface[] $forms */
$forms = iterator_to_array($forms);
$forms['model_id']->setData($formData);

}

public function mapFormsToData($forms, &$data)
{
//$forms = iterator_to_array($forms);
$data = [
'model_id' => iterator_to_array($data)
];
}

缺少的部分是当我使用调试器调查 mapFormsToData 时:
  • $forms 是一个 RecursiveIteratorIterator
  • $data 是一个 PagerFanta 对象

  • 我明白我必须如何通过 PagerFanta 对象“循环”,因为它没有 ArrayAccess,但是实际上勾选了哪些复选框的数据在哪里?此外,此处无法访问我的其他表单字段(操作)

    最佳答案

    我认为你的方法有问题。 Form 组件旨在修改传递给它的对象,据我所知,这不是您想要的。您不想修改 Pagerfanta 对象,而是想为批量操作选择实体。

    因此,为了解决您的问题,必须发生非常原始的事情:必须在页面上显示一个 <form>,并为每个作为批量操作候选的条目显示一个复选框,并使用一些按钮来触发批量操作( s)。

    据我所知,您的表单 - 除了复选框条目之外 - 没问题,我猜并不是您的问题。您甚至对编辑 Pagerfanta 对象(我希望)不感兴趣,只想要选择。为此,我们通过一个选项将排队显示在页面上的对象集合提供给表单,然后使用该选项构建字段(读取:将集合传递给 EntityType 字段)。

    将集合添加到表单(调用)作为选项:

    在你的 Controller 中,你应该有类似的东西:

    $form = $this->createForm(ModelEntitySelectionType::class, $pagerfanta);

    将此更改为:
    $form = $this->createForm(ModelEntitySelectionType::class, [], [
    'model_choices' => $pagerfanta->getCurrentPageResults(),
    ]);

    方法 getCurrentPageResults 返回当前页面的实体集合(显然)。作为第二个参数的空数组 [] 最终是您尝试编辑/创建的对象/数组。我在这里选择了一个数组,但您也可以将其设置为一个新的操作类(如 DTO),例如 ModelBulkAction 具有属性: modelaction :
    class ModelBulkAction {
    public $model;
    public $action;
    }

    请注意,这些类型的对象只有在不止一个地方使用时才有意义。
    那么电话将是:
    $form = $this->createForm(ModelEntitySelectionType::class, new ModelBulkAction(), [
    'model_choices' => $pagerfanta->getCurrentPageResults(),
    ]);

    将选择传递给子表单:

    如果您为表单提供一个选项,而表单不期望该选项,则 Form 组件会提示。这就是 AbstractType::configureOptions(OptionsResolver $resolver) 的目的。 (旁注:我不知道,你的 setDefaultOptions 应该实现什么,tbh,尽管如此,还有一个 ExceptionInterface。真的不知道。)
    public function configureOptions(OptionsResolver $resolver) {
    $resolver->setRequired([
    'model_choices', // adds model_choices as a REQUIRED option!
    ]);
    $resolver->setDefaults([
    // change null to ModelBulkAction::class, if applicable
    'data_class' => null,
    ]);
    }

    最后实际将集合传递给实体类型子表单:
        // in ModelEntitySelectionType::buildForm($builder, $options)

    $builder->add('model', EntityType::class, [
    'required' => false,
    'class' => ModelFile::class,
    'choice_label' => 'id',
    'choices' => $options['model_choices'], // set the choices explicitly
    'multiple' => true,
    'expanded' => true,
    ])
    // ...
    ;

    此外,不再需要您的数据映射,应将其删除。

    将表单小部件添加到输出

    这与您链接的stackoverflow问题和答案非常相似。但是,表单中的键是不同的,因为我的方法略有不同:
    {{ form_start(form) }}
    {% for entity in pagerfanta %}

    {# stuff before the checkbox #}
    {{ form_widget(form.model[entity.id]) }}
    {# stuff after the checkbox #}

    {% endfor %}
    {# place the selection of action somewhere! and possibly the "submit" button #}
    {{ form_widget(form.action) }}
    {{ form_end(form) }}

    (注意:这可能会在复选框旁边显示条目的 id,因为那是您的 choice_label ,我相信这可以通过: {{ form_widget(form.model[index], {label:false}) }} 或通过将 choice_label 设置为 false 而不是 0x1045 来删除)。

    获取您的批量实体

    'id' 之后,您可以检查提交和表单值:
    if($form->isSubmitted() && $form->isValid()) {
    $data = $form->getData();
    // $data['model'] contains an array of entities, that were selected
    // $data['action'] contains the selection of the action field

    // do the bulk action ...
    }

    如果您实现了 $form->handleRequest($request); 方法,则 ModelBulkAction 是那种对象,并且有 $data$data->model 供您使用(或传递给存储库)。

    更多东西

    显然 $data->action 选项几乎可以按您喜欢的任何方式命名(但不应与 model_choices 可能具有的现有 options 冲突)。

    要使实体可选(除了复选框),您可以例如使用 AbstractType 作为非 JavaScript 方法(可以添加样式)。对于 js,它几乎无关紧要,因为您可能只需要选择行中的第一个复选框。

    备择方案

    除了向表单提供对象集合之外,理论上您还可以提供一个 id 列表并使用 <label for="{{ form.model[index].vars.id }}"><!-- something to click --></label> 而不是 ChoiceType 。不过,这也没什么可收获的。

    我希望这有帮助。

    关于forms - 以批量形式使用 Pagerfanta/非 ArrayAccess 列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57405279/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com