如何将数据传递到 CollectionType 表单并将其获取到那里?
How to pass data into CollectionType form and get it there?
如何以正确的方式获取发送到集合中的数据?
重要:
If I delete from the Create Form class this line:
'data'=> array_values($builder->getData()->cpus), //TODO: shit code send data And add in Collection
And add in Collection Form class this:
'data_class' => Command::class, //namespace (Collection\Command)
This works only in view (twig) stage, but firstly I have to get those
data before creating collection form (view).
我该怎么做?
此刻我找到了这个解决方案(看起来 "shitty"):)。标记为 TODO
的行
Collection\Command:
class Command
{
public $id_item;
/**
* @var ItemInterface $interface
*/
public $interface;
public $id_object;
public function __construct(string $id_item, ItemInterface $interface)
{
$this->id_item = $id_item;
$this->interface = $interface;
}
public function getIdItem(): string
{
return $this->id_item;
}
public function getInterface(): ItemInterface
{
return $this->interface;
}
}
有问题,我无法很好地从 $cpus 获取数据 :)
Collection\Form:
class Form extends AbstractType
{
private $cpuModelFetcher;
public function __construct(CpuModelFetcher $cpuModelFetcher)
{
$this->cpuModelFetcher = $cpuModelFetcher;
}
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$index = (int)$builder->getName(); //TODO: shit code - use name of form as index.
/**
* @var Command $command
*/
$command = $builder->getData()[$index]; //TODO: shit code get data from array
$builder
->add('id_object', Type\ChoiceType::class,
[
'choices' => array_flip($this->cpuModelFetcher->getSupportedCpuModelListForModelBasedDeviceBySocketType(
$command->getIdItem(),$command->getInterface()->getId())),
'placeholder' => 'not installed in '.$command->getInterface()->getName().' socket.',
'required' => false,
]);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults(array(
//'data_class' => Command::class,
'data_class' => null,
));
}
}
创建命令:
class Command
{
/**
* @Assert\NotBlank()
*/
private $id;
public $cpus;
private function __construct(Id $id)
{
$this->id = $id;
}
public static function fromDevice(Device $device): self
{
$command = new self($device->getId());
if($device->getBasedType()->isModelBasedDevice()){
$command->cpus = $command->transformDeviceModelInterfaceCollectionToCommandArray($device->getId(),
$device->getModelBasedDevice()->getDeviceModel()->getCpuInterfaces());
}
return $command;
}
private function transformDeviceModelInterfaceCollectionToCommandArray(Id $id_item, ArrayCollection $interfaces): array
{
$object_specific_interfaces = [];
foreach ($interfaces as $one){
/**
* @var DeviceModelInterface $one
*/
for($i=0; $i<$one->getAmount(); $i++){
$object_specific_interfaces[] = new Collection\Command($id_item->getValue(), $one->getInterface());
}
}
unset($one);
return $object_specific_interfaces;
}
}
创建表单:
class Form extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
//dump($builder);
$builder
->add('cpus', CollectionType::class, [
'label' => false,
'entry_type' => Collection\Form::class,
'entry_options' => [
'label' => false,
'data'=> array_values($builder->getData()->cpus), //TODO: shit code send data
],
'by_reference' => true,
'allow_add' => false,
'allow_delete' => false,
'delete_empty' => true,
])
->add('save', Type\SubmitType::class, [
'attr' => ['class' => 'btn btn-primary'],
]);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults(array(
'data_class' => Command::class,
));
}
}
感谢您的帮助。
我发现这个解决方案看起来更好,我只是从 class Collection\Form.
中的 PRE_SET_DATA 事件中获取数据
class Form extends AbstractType
{
private $cpuModelFetcher;
public function __construct(CpuModelFetcher $cpuModelFetcher)
{
$this->cpuModelFetcher = $cpuModelFetcher;
}
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->addEventListener(FormEvents::PRE_SET_DATA, array($this, 'onPreSetData'));
}
protected function addElements(FormInterface $form, $data): void
{
/**
* @var Command $data
*/
$form->add('id_object', Type\ChoiceType::class,
[
'choices' => array_flip($this->cpuModelFetcher->getSupportedCpuModelListForModelBasedDeviceBySocketType(
$data->getIdItem(), $data->getInterface()->getId())),
'placeholder' => 'not installed in '.$data->getInterface()->getName().' socket.',
'required' => false,
]);
//dump($data);
//dump($form);
}
function onPreSetData(FormEvent $event): void
{
$form = $event->getForm();
$data = $event->getData();
$this->addElements($form, $data);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults(array(
'data_class' => Command::class,
));
}
}
无论如何,如果有人知道其他解决方案,我将很高兴听到。
谢谢。
如何以正确的方式获取发送到集合中的数据?
重要:
If I delete from the Create Form class this line:
'data'=> array_values($builder->getData()->cpus), //TODO: shit code send data And add in Collection
And add in Collection Form class this:
'data_class' => Command::class, //namespace (Collection\Command)
This works only in view (twig) stage, but firstly I have to get those data before creating collection form (view).
我该怎么做?
此刻我找到了这个解决方案(看起来 "shitty"):)。标记为 TODO
的行Collection\Command:
class Command
{
public $id_item;
/**
* @var ItemInterface $interface
*/
public $interface;
public $id_object;
public function __construct(string $id_item, ItemInterface $interface)
{
$this->id_item = $id_item;
$this->interface = $interface;
}
public function getIdItem(): string
{
return $this->id_item;
}
public function getInterface(): ItemInterface
{
return $this->interface;
}
}
有问题,我无法很好地从 $cpus 获取数据 :)
Collection\Form:
class Form extends AbstractType
{
private $cpuModelFetcher;
public function __construct(CpuModelFetcher $cpuModelFetcher)
{
$this->cpuModelFetcher = $cpuModelFetcher;
}
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$index = (int)$builder->getName(); //TODO: shit code - use name of form as index.
/**
* @var Command $command
*/
$command = $builder->getData()[$index]; //TODO: shit code get data from array
$builder
->add('id_object', Type\ChoiceType::class,
[
'choices' => array_flip($this->cpuModelFetcher->getSupportedCpuModelListForModelBasedDeviceBySocketType(
$command->getIdItem(),$command->getInterface()->getId())),
'placeholder' => 'not installed in '.$command->getInterface()->getName().' socket.',
'required' => false,
]);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults(array(
//'data_class' => Command::class,
'data_class' => null,
));
}
}
创建命令:
class Command
{
/**
* @Assert\NotBlank()
*/
private $id;
public $cpus;
private function __construct(Id $id)
{
$this->id = $id;
}
public static function fromDevice(Device $device): self
{
$command = new self($device->getId());
if($device->getBasedType()->isModelBasedDevice()){
$command->cpus = $command->transformDeviceModelInterfaceCollectionToCommandArray($device->getId(),
$device->getModelBasedDevice()->getDeviceModel()->getCpuInterfaces());
}
return $command;
}
private function transformDeviceModelInterfaceCollectionToCommandArray(Id $id_item, ArrayCollection $interfaces): array
{
$object_specific_interfaces = [];
foreach ($interfaces as $one){
/**
* @var DeviceModelInterface $one
*/
for($i=0; $i<$one->getAmount(); $i++){
$object_specific_interfaces[] = new Collection\Command($id_item->getValue(), $one->getInterface());
}
}
unset($one);
return $object_specific_interfaces;
}
}
创建表单:
class Form extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
//dump($builder);
$builder
->add('cpus', CollectionType::class, [
'label' => false,
'entry_type' => Collection\Form::class,
'entry_options' => [
'label' => false,
'data'=> array_values($builder->getData()->cpus), //TODO: shit code send data
],
'by_reference' => true,
'allow_add' => false,
'allow_delete' => false,
'delete_empty' => true,
])
->add('save', Type\SubmitType::class, [
'attr' => ['class' => 'btn btn-primary'],
]);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults(array(
'data_class' => Command::class,
));
}
}
感谢您的帮助。
我发现这个解决方案看起来更好,我只是从 class Collection\Form.
中的 PRE_SET_DATA 事件中获取数据class Form extends AbstractType
{
private $cpuModelFetcher;
public function __construct(CpuModelFetcher $cpuModelFetcher)
{
$this->cpuModelFetcher = $cpuModelFetcher;
}
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->addEventListener(FormEvents::PRE_SET_DATA, array($this, 'onPreSetData'));
}
protected function addElements(FormInterface $form, $data): void
{
/**
* @var Command $data
*/
$form->add('id_object', Type\ChoiceType::class,
[
'choices' => array_flip($this->cpuModelFetcher->getSupportedCpuModelListForModelBasedDeviceBySocketType(
$data->getIdItem(), $data->getInterface()->getId())),
'placeholder' => 'not installed in '.$data->getInterface()->getName().' socket.',
'required' => false,
]);
//dump($data);
//dump($form);
}
function onPreSetData(FormEvent $event): void
{
$form = $event->getForm();
$data = $event->getData();
$this->addElements($form, $data);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults(array(
'data_class' => Command::class,
));
}
}
无论如何,如果有人知道其他解决方案,我将很高兴听到。
谢谢。