问题
Good day everyone
I have Product entity that related to ProductType entity with many-to-one relation
I have the custom ProductsType field based on 'entity' field type:
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';
}
}
The 'oq_products_selector_widget' code:
{% 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 %}
But when i try to render the form there is an exception:
Impossible to access an attribute ("id") on a null variable
As i understand the related entity data did not passed to choice data array and cannot be shown via choices[id].data.productType.name
How can i pass this data to choice?
回答1:
Hm, i solved that trouble.
I suppose that entity field type hydrates the objects for choice array without related entities. So i switched my custom field type parent to 'choice', then i received all the entities for choices with EntityManager and standart repository's findAll
method and got data from all linked entities (ProductType) without any problems
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';
}
}
As you can see i get all entities for choices and placed 'em in array. Then i get all the related entities names and placed them into another array. And passed this array to choices with 'choice_attr' => $choicesAttrs
parameter.
After that i have got an access to these additional data
{% 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 %}
来源:https://stackoverflow.com/questions/33913192/symfony-how-to-pass-related-entity-data-to-entity-fields-choices