我们有一个监控服务,我们的监控单位监视某些机器。
我正在创建一个表单,以便在Symfony2中注册一台新机器。
所以我们有机器实体
和监视器实体
对于一台新机器,客户需要用以下内容填充表单:
附着式name
现在,如果我制作一个表单,作为数据支持,一个机器实体,我没有“字段”来要求序列号。Symfony不允许这样做,因为后台实体没有一个名为“序列号”的字段。
我如何才能:
我想我可以:
正如@weaverryan在这篇优秀文章中所描述的那样,pity.
我希望我解释得对。我想很多人不得不解决这个问题。我想我只是在查看一些非常标准的Symfony功能,只是因为我不知道它的名称是什么:-)
发布于 2011-10-04 15:10:50
首先,您应该使用关系--也就是说机器有一个监视器。我认为人们对此有问题,因为当你习惯用“id”和外键来思考事物时,以一种完全面向对象的方式思考关系是新的:)。
因此,假设您的机器与监视器相关,您现在可以创建一个嵌入MonitorType的MonitorType(它将是一个带有序列号字段的表单)。然后,在提交复合表单时,将使用Monitor类上序列化号的约束。
默认情况下,当您绑定所有这些时,它将创建一个新的Machine对象,并通过$machine->getMonitor()提供一个新的Monitor对象。如果持久化,这将是两个插入。但是,我猜您更愿意通过它的序列号查找监视器,并使用现有的监视器,对吗?这样做很容易,只是短路后,你的形式.
$form = new MachineType();
$form->bindRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getEntityManager();
$machine = $form->getData();
$serialNumber = $machine->getMonitor->getSerialNumber();
$existingMonitor = $em
->getRepository('YourBundle:Monitor')
->findOneBy(array('serialNumber' => $serialNumber));
if ($existingMonitory) {
$machine->setMonitor($existingMonitor);
}
$em->persist($machine);
$em->persist($machine->getMonitor());
$em->flush();
// ...
}所以这就是我的想法。最重要的是,如果不利用人际关系,你就会使自己处于不利地位。您可以看到,通过将这两个表单嵌入在一起,您确实可以自然地访问序列号字段。
祝好运!
发布于 2011-10-18 20:37:29
最近,我通过创建一个自定义表单类型(在我的例子中称为“选择器”)解决了这个问题,它附带了一个数据转换器,它通过串行方式返回监视器:
机器类型:
class MachineType extends AbstractType {
public function buildForm(FormBuilder $builder, array $options) {
$builder->add('name');
$builder->add('monitor', 'monitor_selector_type');
}
public function getName() {
return 'machine;
}
}监视器选择器类型(最终,这将只是一个文本字段(默认类型父类型是" text "),您将在其中输入监视器序列。如果输入了不存在的序列,该字段将显示一个错误。
class MonitorSelectorType extends AbstractType {
private $doctrine
public function __construct(Registry $doctrine) {
$this->doctrine = $doctrine;
}
public function buildForm(FormBuilder $builder, array $options) {
$transformer = new MonitorToSerialTransformer($this->doctrine->getEntityManager());
$builder->appendClientTransformer($transformer);
}
public function getDefaultOptions(array $options) {
return array(
'invalid_message'=>'The selected monitor does not exist',
'error_bubbling'=>false
);
}
public function getName() {
return 'machine;
}
}该类将串行转换为实际监视器,将实际监视器转换为串行
class MonitorToSerialTransformer {
private $em
public function __construct(EntityManager $em) {
$this->em = $em;
}
public function transform($val) {
if (null === $val) {
return '';
}
return $val->getSerial();
}
public function reverseTransform($val) {
if (!$val) {
return null;
}
$monitor = $this->em->getRepository('xBundle:Monitor')->findOneBy(array('serial' => $val));
if (null === $monitor) {
throw new TransformationFailedException('A monitor with serial '.$val.' does not exist!');
}
return $monitor;
}
}最后,使用id "monitor_selector_type“和标记"form.type”在服务容器中注册form.type,并向其注入理论。
现在,在应用程序中的任意随机位置,使用这种选择器类型按ID选择监视器是非常容易的,完全不需要向Controller添加逻辑。
如果您希望在输入未知序列时创建一个新监视器,则可以实例化它,而不是抛出TransformationFailedException,如果机器没有监视器的级联选项,甚至可以将它保存到实体管理器。
你好,巴特
https://stackoverflow.com/questions/7648117
复制相似问题