2

我正在为 symfony3 表单和 CollectionType 类苦苦挣扎:

我有一个包含几个复杂表单的页面。我不使用任何数据库(经过验证的表单被发送到外部 REST 服务)

现在假设我的请求有一个名为“ProductService”的实体对象:

class ProductService
{
    /** @var string */
    private $msg;

    /** @var array*/
    private $products
}

还有一个 ProductServiceType 类来呈现表单:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('products', CollectionType::class, [
            'entry_type'   => ProductType::class,
        ])
        ->add('msg' [...]);
}

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'data_class' => ProductService::class,
    ]);
}

有了这个设置,一切都像魅力一样工作,所有产品都将添加到我实体的产品数组中。问题是,我希望 $products 是一个 SplObjectStorage 对象:

class ProductService
{
    /** @var string */
    private $msg;

    /** @var SplObjectStorage */
    private $products
}

如果我将它设置为此并在其中附加一个空对象,symfony 将无法再呈现表单。它抛出以下错误: 警告:SplObjectStorage::offsetExists() 期望参数 1 是对象,给定字符串

那么,谁能告诉我,当不使用教义和 orm 时如何处理实体中的 collectionType?是使用数组的唯一可能性,还是这种情况有任何文档,我没有找到?(我仍然想知道 symfony 是如何调用 offsetExists 的,必须实现一些东西来处理 SplObjectStorage,还是我错了?)

4

1 回答 1

1

我相信你的错误是因为没有实现表单集合来处理你所期望的 SplObjectStorage。您可以在 symfony 存储库中为它创建一个问题。

当 symfony 试图通过以这种方式从 ProductService 读取您的产品来填充表单集合时,会导致该错误:

$products = $productService->getProducts();
$products->offsetExists(0); //here is the error.

因为它期望任何实现 ArrayAccess 的存储都将以这种方式读取,但对于 SplObjectStorage 并非如此。

表单元素有一个设置property_path 链接,您可以利用它来解决您的问题。

我的解决方案是使用此设置并返回一个数组来填充您的集合:

$builder
        ->add('products', CollectionType::class, [
            'entry_type'   => ProductType::class,
            'property_path' => 'productsArray'
        ])

class ProductService
{

... 
public function getProductsArray() {
    $prArray= [];
    foreach ($this->products as $value) {
        $prArray[] = $value;
    }
    return $prArray;
}

这样,您可以使用生成的数组填充表单集合。

我认为另一种解决方案是使用数据转换器。希望这可以帮助

于 2017-11-19T21:01:26.723 回答