我偶然发现了一种奇怪的行为,即使现在可行,我仍然不确定我的解决方案是否最合适。
我有2个实体:
class Recipe
{
/** [...] */
public $id;
/** @ORM\Column(type="string", length=255) */
public $name;
/** @ORM\ManyToOne(targetEntity="App\Entity\Location") */
public $location;
}
class Location
{
/** [...] */
public $id;
/** @ORM\Column(type="string", length=255) */
public $name;
/** @ORM\OneToMany(targetEntity="App\Entity\Recipe", mappedBy="location") */
protected $recipes;
}
这里没什么好看的。一个位置可以容纳多个食谱,一个食谱最多可以位于一个位置。
配方形式如下:
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add(
'name',
TextType::class,
['label' => 'Name',]
)
->add(
'location',
EntityType::class,
[
'label' => 'Location',
'class' => \App\Entity\Location::class,
'choice_value' => function ($location) {
// Why is this code necessary?
return is_object($location)
? $location->getId() // Object passed (when building choices)
: $location; // int value passed (when checking for selection)
},
'choice_label' => 'name',
]
)
;
}
然后控制器创建表单,依此类推。
/**
* @ParamConverter("entity", class="App:Recipe", isOptional="true")
*/
public function edit(Request $request, object $entity = null) {
$form = $this->createForm(\App\Form\Recipe::class, $entity ?? new Recipe());
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// ...
}
// ...
}
我的原始实现在choice_value
表单元素上没有上面的EntityType
回调,并且在打开现有位置时从未选择该选项。但是除此之外,一切都按预期进行,选择一个值 did 将其正确保存到数据库中,无需其他代码,而只是Symfony的魔力。
您能告诉我为什么这里需要choice_value
吗?我错过了什么?
为什么作为参数传递的值有时是对象,有时是整数?
答案 0 :(得分:0)
通常没有必要。也许是因为您的实体之间的关系是单向的?
有效的示例:
在实体级别
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Level", inversedBy="steps")
*/
private $level;
在实体步骤
/**
* @ORM\OneToMany(targetEntity="App\Entity\Step", mappedBy="level")
*/
private $steps;
然后StepType:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('level', EntityType::class, [
'label' => 'Related level',
'class' => Level::class,
'choice_label' => 'position'
])
;
}
答案 1 :(得分:0)
我不知道是不是问题的原因,但是对于public void Start(ICallback callback)
{
if (Callback != null)
Stop();
Console.WriteLine("STARTING");
Callback = callback;
cancellation = new CancellationTokenSource();
this.task = TaskLoopAsync();
Console.WriteLine("STARTED");
}
public async void Stop()
{
if (Callback == null)
{
Console.WriteLine("ALREADY stopped");
return;
}
Console.WriteLine("STOPPING");
cancellation.Cancel();
try
{
await task;
}
catch (Exception e)
{
Console.WriteLine($"{e.Message}");
}
finally
{
cancellation.Dispose();
cancellation = null;
Callback = null;
task = null;
Console.WriteLine("STOPPED");
}
}
private async void TaskLoopAsync()
{
int i = 0;
while (!cancellation.IsCancellationRequested)
{
await Task.Delay(1000);
Console.WriteLine("Starting iteration... {0}", i);
Callback.SendMessage($"Iteration {i} at {System.DateTime.Now}");
Console.WriteLine("...Ending iteration {0}", i++);
}
Console.WriteLine("CANCELLED");
}
字段,您不需要手动设置EntityType
。
来自Symfony docs:
在EntityType中,默认情况下将其覆盖以使用id。使用ID时,Doctrine仅查询对象中实际提交的ID。
答案 2 :(得分:0)
哦...找到了。实际上,我有一个与该字段相关联的旧DataTransformer
,它弄乱了值。我已经不再需要它了,所以只需将其神奇地删除即可解决该错误。
无论如何,感谢您的帮助,它确实确认了某些错误,并迫使我进行更深入的研究。