首页 文章

Symfony - 如何将相关实体数据传递给实体字段的选择

提问于
浏览
1

今天是个好日子

我有与ProductType实体相关的Product实体,具有多对一关系

我有基于'entity'字段类型的自定义ProductsType字段:

class ProductsType extends AbstractType
{

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {

        $resolver->setDefaults(
            [
                'label' => 'oq.company.interest.label',
                'class' => 'OQReferenceBundle:Product',
                'required' => false,
                'expanded' => true,
                'multiple' => true,
                'choice_label' => 'name',
                'empty_value' => 'oq.reference.interest.choose',
                'query_builder' => function ($repository) {
                    $qb = $repository->createQueryBuilder('p');

                    $qb->leftJoin('OQReferenceBundle:ProductType', 'pt', 'WITH', 'p.productType = pt.id')
                        ->addOrderBy('pt.name', 'ASC')
                        ->addOrderBy('p.name', 'ASC');

                    return $qb;
                },
            ]
        );
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'oq_products_selector';
    }

    /**
     * @return string
     */
    public function getParent()
    {
        return 'entity';
    }
}

'oq_products_selector_widget'代码:

{% block oq_products_selector_widget %}

    <div {{ block('widget_container_attributes') }}>

        {% for id, child in form %}
            <div class="oro-clearfix">
                {{ form_widget(child) }}
                <label for="{{ child.vars.id }}">
                    {{ choices[id].data.name }} ({{ choices[id].data.productType.name }})
                </label>
            </div>
        {% endfor %}

    </div>

{% endblock %}

但是,当我尝试渲染表单时,有一个例外:

无法访问null变量的属性(“id”)

据我所知,相关实体数据没有传递给选择数据数组,无法通过 choices[id].data.productType.name 显示

我如何将这些数据传递给选择?

1 回答

  • 0

    嗯,我解决了那个麻烦 .

    我想实体字段类型为没有相关实体的选择数组水合对象 . 所以我将自定义字段类型父级切换为'choice',然后我收到了所有实体,用于选择EntityManager和标准存储库的 findAll 方法,并从所有链接实体(ProductType)获取数据,没有任何问题

    The code

    class ProductsType extends AbstractType
    {
    
        /** @var EntityManager */
        protected $em;
    
        public function __construct(EntityManager $em)
        {
            $this->em = $em;
        }
    
        /**
         * {@inheritdoc}
         */
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder->addModelTransformer(new ProductsTransformer($this->em));
        }
    
        /**
         * @param OptionsResolverInterface $resolver
         */
        public function setDefaultOptions(OptionsResolverInterface $resolver)
        {
    
            $choices = array();
            $choicesAttrs = array();
    
            /** @var ProductRepository $repo */
            $repo = $this->em->getRepository("OQReferenceBundle:Product");
            if ($products = $repo->getProductsSortedByProductType()) {
                /** @var Product $product */
                foreach ($products as $product) {
                    $choices[$product->getId()] = $product->getName();
                    $choicesAttrs[$product->getName()] = array('data-product-type' => $product->getProductType()->getName());
                }
            }
    
            $resolver->setDefaults(
                [
                    'label' => 'oq.company.interest.label',
                    'required' => false,
                    'expanded' => true,
                    'multiple' => true,
                    'empty_value' => 'oq.reference.interest.choose',
                    'choices' => $choices,
                    'choice_attr' => $choicesAttrs,
                ]
            );
        }
    
        /**
         * @return string
         */
        public function getName()
        {
            return 'oq_products_selector';
        }
    
        /**
         * @return string
         */
        public function getParent()
        {
            return 'choice';
        }
    }
    

    正如你所看到的,我得到所有实体的选择并将它们放在数组中 . 然后我得到所有相关的实体名称并将它们放入另一个数组中 . 并将此数组传递给 'choice_attr' => $choicesAttrs 参数的选项 .

    之后我可以访问这些附加数据

    {% block oq_products_selector_widget %}
    
        <div {{ block('widget_container_attributes') }}>
            <div class="horizontal">
    
                {% set productType = '' %}
    
                {% for id, child in form %}
                    <div class="oro-clearfix">
    
                        {% if productType != child.vars.attr['data-product-type'] %}
                            {% set productType = child.vars.attr['data-product-type'] %}
                            <div style="margin-bottom: 6px;">
                                <strong>{{ productType }}</strong>
                            </div>
                        {% endif %}
    
                        {{ form_widget(child) }}
                        <label for="{{ child.vars.id }}">
                            {{ child.vars.label }}
                        </label>
                    </div>
                {% endfor %}
    
            </div>
        </div>
    
    {% endblock %}
    

相关问题