EasyAdmin 3.X - Как увидеть связанные объекты `toString` вместо номера ассоциации в списке?

У меня есть объект Product с отношением ManyToMany к объекту Category

/**
 * @ORM\ManyToMany(targetEntity="App\Domain\Category", inversedBy="stalls")
 */
private $categories;

//...

/**
 * @return Collection|Category[]
 */
public function getCategories(): Collection
{
    return $this->categories;
}

В классе ProductCrudController у меня есть следующий метод configureFields:

public function configureFields(string $pageName): iterable
{
    return [
        Field::new('name'),
        Field::new('description'),
        AssociationField::new('categories'),
    ];
}

При создании/редактировании Product в отношении все работает как положено, но в списке товаров вместо отображения связанных категорий я вижу количество категорий, которые есть у товара. Как я могу изменить это поведение?

На следующем изображении первый продукт имеет 1 категорию, а второй в списке — 2 разные категории. Я хотел бы, чтобы название категорий отображалось здесь.

введите здесь описание изображения

В качестве примечания: класс Category имеет метод __toString, возвращающий имя категории.

РЕДАКТИРОВАТЬ:

Поведение, которое я ищу, такое же, как у столбца Tags на следующем изображении:

введите здесь описание изображения


person hosseio    schedule 03.09.2020    source источник


Ответы (4)


Вы можете отформатировать значение, используя метод formatValue следующим образом:

->formatValue(function ($value, $entity) {
                $str = $entity->getCategories()[0];
                for ($i = 1; $i < $entity->getCategories()->count(); $i++) {
                    $str = $str . ", " . $entity->getCategories()[$i];
                }
                return $str;
              })
person br-dev    schedule 07.09.2020
comment
Я попробую эту formatValue функцию, спасибо. Возможно, для вашего решения вы можете использовать implode (php.net/manual/ en/function.implode.php), чтобы вернуть тот же результат? - person hosseio; 09.09.2020
comment
Очень хорошее решение, но обратите внимание, что в его нынешнем виде это не позволяет повторно использовать код, если вам это нужно для нескольких объектов. - person Robin Bastiaan; 08.03.2021

Вы можете сделать шаблон для этого следующим образом:

// somewhere here templates/admin/field/category.html.twig
{% for category in field.value %}
  {%- set url = ea_url()
    .setController('Path\\To\\Your\\CategoryCrudController')
    .setAction('detail')
    .setEntityId(category.id)
  -%}
  <a href="{{ url }}">
    {{ category.name }}{% if not loop.last %}, {% endif %}
  </a>
{% else %}  
  <span class="badge badge-secondary">None</span>
{% endfor %}

И просто добавьте его в поле

// in ProductCrudController
AssociationField::new('categories')->setTemplatePath('admin/field/category.html.twig'),
person Flash    schedule 30.11.2020

У меня была такая же проблема на моей странице сведений. Поэтому вместо шаблона я меняю тип поля в зависимости от pagename

if (Crud::PAGE_DETAIL === $pageName) {
   $field = ArrayField::new('field')->setLabel('label');
} else {
   $field = AssociationField::new('field')->setLabel('label');
}
person Gino    schedule 31.01.2021

Используйте ArrayField::new('categories'), вместо AssociationField::new('categories'), в crud-контроллере.

При создании/редактировании товара теперь отображение другое, но достаточно хорошее

person hosseio    schedule 03.09.2020