首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Symfony2表单,其中的数据对象与需要填充的内容不完全匹配

问Symfony2表单,其中的数据对象与需要填充的内容不完全匹配
EN

Stack Overflow用户
提问于 2011-10-04 12:47:57
回答 2查看 1.6K关注 0票数 2

我们有一个监控服务,我们的监控单位监视某些机器。

我正在创建一个表单,以便在Symfony2中注册一台新机器。

所以我们有机器实体

  • id
  • machine名称
  • 监视器id

和监视器实体

  • id
  • serialnumber
  • ...

对于一台新机器,客户需要用以下内容填充表单:

附着式name

  • serialnumber monitor

  • ...

  • 机

现在,如果我制作一个表单,作为数据支持,一个机器实体,我没有“字段”来要求序列号。Symfony不允许这样做,因为后台实体没有一个名为“序列号”的字段。

我如何才能:

  • 询问序列号,而支持实体
  • 中没有这样的字段,如果我获得序列号,如何将其与其内部id链接起来,以便在验证和绑定数据后与实体保持

我想我可以:

正如@weaverryan在这篇优秀文章中所描述的那样,pity.

  • provide

  • 创建了一个没有对象的表单:http://knplabs.com/en/blog-csi/symfony-validators-standalone --通过这种方式,我可以自己进行持久化操作,但对于自定义表单和机器实体(这是某种链接),需要单独的约束,这样Symfony就知道在哪里可以得到序列化字段存在的事实,以及它的约束是什么。也许是通过定义一种关系?我希望避免实体代码中的关系,因为我在邮件列表中看到了很多问题,但也许我别无选择:-)

  • ,还有什么?

我希望我解释得对。我想很多人不得不解决这个问题。我想我只是在查看一些非常标准的Symfony功能,只是因为我不知道它的名称是什么:-)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-10-04 15:10:50

首先,您应该使用关系--也就是说机器有一个监视器。我认为人们对此有问题,因为当你习惯用“id”和外键来思考事物时,以一种完全面向对象的方式思考关系是新的:)。

因此,假设您的机器与监视器相关,您现在可以创建一个嵌入MonitorType的MonitorType(它将是一个带有序列号字段的表单)。然后,在提交复合表单时,将使用Monitor类上序列化号的约束。

默认情况下,当您绑定所有这些时,它将创建一个新的Machine对象,并通过$machine->getMonitor()提供一个新的Monitor对象。如果持久化,这将是两个插入。但是,我猜您更愿意通过它的序列号查找监视器,并使用现有的监视器,对吗?这样做很容易,只是短路后,你的形式.

代码语言:javascript
复制
$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();

    // ...
}

所以这就是我的想法。最重要的是,如果不利用人际关系,你就会使自己处于不利地位。您可以看到,通过将这两个表单嵌入在一起,您确实可以自然地访问序列号字段。

祝好运!

票数 5
EN

Stack Overflow用户

发布于 2011-10-18 20:37:29

最近,我通过创建一个自定义表单类型(在我的例子中称为“选择器”)解决了这个问题,它附带了一个数据转换器,它通过串行方式返回监视器:

机器类型:

代码语言:javascript
复制
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 "),您将在其中输入监视器序列。如果输入了不存在的序列,该字段将显示一个错误。

代码语言:javascript
复制
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;
    }
}

该类将串行转换为实际监视器,将实际监视器转换为串行

代码语言:javascript
复制
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,如果机器没有监视器的级联选项,甚至可以将它保存到实体管理器。

你好,巴特

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7648117

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档