跳到内容

操作

编辑此页

操作 是您可以在 CRUD 页面上执行的每个任务。例如,在 `index` 页面中,您可以执行“编辑”和“删除”列表中显示的每个实体的任务,以及执行“创建”新实体的另一个任务。

操作在您的 仪表盘CRUD 控制器 的 `configureActions()` 方法中配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
namespace App\Controller\Admin;

use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;

class ProductCrudController extends AbstractCrudController
{
    // ...

    public function configureActions(Actions $actions): Actions
    {
        // ...
    }
}

操作名称和常量

某些方法需要操作名称作为参数。除了使用操作名称的纯字符串(例如 `'index'`、`'detail'`、`'edit'` 等),您还可以使用这些值的常量:`Action::INDEX`、`Action::DETAIL`、`Action::EDIT` 等 (它们在 `EasyCorp\Bundle\EasyAdminBundle\Config\Action` 类中定义)。

内置操作

以下是每个页面默认包含的内置操作

  • 页面 `Crud::PAGE_INDEX` (`'index'`)

    • 默认全局添加:`Action::NEW`
    • 默认每个条目添加:`Action::EDIT`、`Action::DELETE`
    • 每个条目的其他可用操作:`Action::DETAIL`
  • 页面 `Crud::PAGE_DETAIL` (`'detail'`)

    • 默认添加:`Action::EDIT`、`Action::DELETE`、`Action::INDEX`
    • 其他可用操作:-
  • 页面 `Crud::PAGE_EDIT` (`'edit'`)

    • 默认添加:`Action::SAVE_AND_RETURN`、`Action::SAVE_AND_CONTINUE`
    • 其他可用操作:`Action::DELETE`、`Action::DETAIL`、`Action::INDEX`
  • 页面 `Crud::PAGE_NEW` (`'new'`)

    • 默认添加:`Action::SAVE_AND_RETURN`、`Action::SAVE_AND_ADD_ANOTHER`
    • 其他可用操作:`Action::SAVE_AND_CONTINUE`、`Action::INDEX`

添加操作

使用 `add()` 方法添加任何内置操作以及您自己的自定义操作(将在本文后面解释)

1
2
3
4
5
6
7
8
9
10
11
12
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;

public function configureActions(Actions $actions): Actions
{
    return $actions
        // ...
        ->add(Crud::PAGE_INDEX, Action::DETAIL)
        ->add(Crud::PAGE_EDIT, Action::SAVE_AND_ADD_ANOTHER)
    ;
}

移除操作

移除操作会使其在界面中不可用,因此用户无法单击按钮/链接来运行这些操作。但是,用户可以破解 URL 来运行操作。要完全禁用操作,请使用稍后解释的 `disable()` 方法

1
2
3
4
5
6
7
8
9
10
11
12
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;

public function configureActions(Actions $actions): Actions
{
    return $actions
        // ...
        ->remove(Crud::PAGE_INDEX, Action::NEW)
        ->remove(Crud::PAGE_DETAIL, Action::EDIT)
    ;
}

更新操作

这主要用于更改内置操作(例如,更改其图标、更新或删除其标签等)。`update()` 方法需要一个可调用对象作为参数,EasyAdmin 会自动将操作传递给它

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;

public function configureActions(Actions $actions): Actions
{
    return $actions
        // ...
        ->update(Crud::PAGE_INDEX, Action::NEW, function (Action $action) {
            return $action->setIcon('fa fa-file-alt')->setLabel(false);
        })

        // in PHP 7.4 and newer you can use arrow functions
        // ->update(Crud::PAGE_INDEX, Action::NEW,
        //     fn (Action $action) => $action->setIcon('fa fa-file-alt')->setLabel(false))
    ;
}

生成动态操作标签

操作标签可以根据与其相关的实体动态生成。例如,`Invoice` 实体可以通过多次付款进行支付。在每个 `Invoice` 详细信息页面的顶部,管理员都希望有一个操作链接(或按钮),将其带到一个自定义页面,该页面显示该发票的已收款项。为了提供更好的用户体验,操作链接(或按钮)标签必须显示当前收到的付款数量(即:`3 payments`)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;

public function configureActions(Actions $actions): Actions
{
    $viewPayments = Action::new('payments')
        ->setLabel(function (Invoice $invoice)) {
            return \count($invoice->getPayments()) . ' payments';
        });

        // in PHP 7.4 and newer you can use arrow functions
        // ->setLabel(fn (Invoice $invoice) => \count($invoice->getPayments()) . ' payments')

    return $actions
        // ...
        ->add(Crud::PAGE_DETAIL, $viewPayments);
}

当相关实体对象不足以计算操作标签时,可以使用任何更具体的服务对象作为委托器。例如,Doctrine 存储库服务对象可用于计算被管理发票的相关付款数量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;

private InvoicePaymentRepository $invoicePaymentRepository;

public function __construct(InvoicePaymentRepository $invoicePaymentRepository)
{
    $this->invoicePaymentRepository = $invoicePaymentRepository;
}

public function configureActions(Actions $actions): Actions
{
    $viewPayments = Action::new('payments')
        ->setLabel(function (Invoice $invoice)) {
            return $this->invoicePaymentRepository->countByInvoice($invoice) . ' payments';
        });

    return $actions
        // ...
        ->add(Crud::PAGE_DETAIL, $viewPayments);
}

有条件地显示操作

某些操作必须仅在满足某些条件时才显示。例如,只有当订单状态为“已付款”时,才可能显示“查看发票”操作。使用 `displayIf()` 方法配置操作何时应向用户可见

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;

public function configureActions(Actions $actions): Actions
{
    $viewInvoice = Action::new('View Invoice', 'fas fa-file-invoice')
        ->displayIf(static function ($entity) {
            return $entity->isPaid();
        });

        // in PHP 7.4 and newer you can use arrow functions
        // ->displayIf(fn ($entity) => $entity->isPaid())

    return $actions
        // ...
        ->add(Crud::PAGE_INDEX, $viewInvoice);
}

注意

`displayIf()` 方法也适用于 全局操作。但是,您的闭包不会接收表示当前实体的对象,因为全局操作不与任何特定实体关联。

禁用操作

禁用操作意味着它不会显示在界面中,即使他们破解 URL,用户也无法运行该操作。如果他们尝试这样做,他们将看到“禁止操作”异常。

操作是全局禁用的,您不能按页面禁用它们

1
2
3
4
5
6
7
8
9
10
11
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;

public function configureActions(Actions $actions): Actions
{
    return $actions
        // ...
        // this will forbid to create or delete entities in the backend
        ->disable(Action::NEW, Action::DELETE)
    ;
}

限制操作

除了禁用操作外,您还可以限制某些用户执行操作。使用 `setPermission()` 定义查看和运行某些操作所需的 Symfony Security 权限。

权限是全局定义的;您不能按页面定义不同的权限

1
2
3
4
5
6
7
8
9
10
11
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;

public function configureActions(Actions $actions): Actions
{
    return $actions
        // ...
        ->setPermission(Action::NEW, 'ROLE_ADMIN')
        ->setPermission(Action::DELETE, 'ROLE_SUPER_ADMIN')
    ;
}

重新排序操作

使用 `reorder()` 定义操作在某些页面中的显示顺序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;

public function configureActions(Actions $actions): Actions
{
    return $actions
        // ...

        // you can reorder built-in actions...
        ->reorder(Crud::PAGE_INDEX, [Action::DETAIL, Action::DELETE, Action::EDIT])

        // ...and your own custom actions too
        ->reorder(Crud::PAGE_INDEX, [Action::DETAIL, 'viewInvoice', Action::DELETE, Action::EDIT])

        // you can pass only a few actions to this method and the rest of actions
        // will be appended in their original order. In the following example, the
        // DELETE and EDIT actions are missing but they will be added automatically
        // after DETAIL and 'viewInvoice' actions
        ->reorder(Crud::PAGE_INDEX, [Action::DETAIL, 'viewInvoice'])
    ;
}

在 `index` 页面中,实体操作(`edit`、`delete` 等)默认显示在下拉列表中。这样做是为了更好地显示每行上的字段内容。如果您希望内联显示所有操作(即,不使用下拉列表),请使用 `showEntityActionsInlined()` 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
namespace App\Controller\Admin;

use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;

class ProductCrudController extends AbstractCrudController
{
    // ...

    public function configureCrud(Crud $crud): Crud
    {
        return $crud
            // ...
            ->showEntityActionsInlined()
        ;
    }
}

添加自定义操作

除了 EasyAdmin 提供的内置操作外,您还可以创建自己的操作。首先,使用 `Action` 类构造函数定义操作的基本信息(名称、标签、图标)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// the only mandatory argument is the internal name of the action (which is
// used to add the action to some pages, to reorder the action position, etc.)
$viewInvoice = Action::new('viewInvoice');

// the second optional argument is the label visible to end users
$viewInvoice = Action::new('viewInvoice', 'Invoice');
// not defining the label explicitly or setting it to NULL means
// that the label is autogenerated from the name (e.g. 'viewInvoice' -> 'View Invoice')
$viewInvoice = Action::new('viewInvoice', null);
// set the label to FALSE to not display any label for this action (but make sure
// to display an icon for the action; otherwise users can't see or click on the action)
$viewInvoice = Action::new('viewInvoice', false);

// the third optional argument is the icon name
$viewInvoice = Action::new('viewInvoice', 'Invoice', 'fa fa-file-invoice');

默认情况下,EasyAdmin 假定图标名称对应于 FontAwesome CSS 类。必要的 CSS 样式和 Web 字体也默认包含在内,因此您无需执行任何其他步骤即可使用 FontAwesome 图标。或者,您可以使用您自己的图标集而不是 FontAwesome。

然后,您可以配置将表示操作的按钮/元素的基本 HTML/CSS 属性

1
2
3
4
5
6
7
8
9
10
11
12
13
$viewInvoice = Action::new('viewInvoice', 'Invoice', 'fa fa-file-invoice')
    // renders the action as a <a> HTML element
    ->displayAsLink()
    // renders the action as a <button> HTML element
    ->displayAsButton()
    // a key-value array of attributes to add to the HTML element
    ->setHtmlAttributes(['data-foo' => 'bar', 'target' => '_blank'])
    // removes all existing CSS classes of the action and sets
    // the given value as the CSS class of the HTML element
    ->setCssClass('btn btn-primary action-foo')
    // adds the given value to the existing CSS classes of the action (this is
    // useful when customizing a built-in action, which already has CSS classes)
    ->addCssClass('some-custom-css-class text-danger')

注意

当使用 `setCssClass()` 或 `addCssClass()` 方法时,操作将丢失 EasyAdmin 应用的默认 CSS 类(`.btn` 和 `.action-<the-action-name>`)。您可能需要手动添加这些 CSS 类,以使您的操作看起来符合预期。

配置基本信息后,使用以下方法之一来定义单击操作时执行的方法

  • `linkToCrudAction()`:执行当前 CRUD 控制器的某些方法;
  • `linkToRoute()`:通过其路由执行某些常规 Symfony 控制器;
  • `linkToUrl()`:访问外部 URL(当您的操作不是由您的应用程序提供服务时很有用)。

以下示例展示了实践中所有类型的操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
namespace App\Controller\Admin;

use App\Entity\Invoice;
use App\Entity\Order;
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;

class OrderCrudController extends AbstractCrudController
{
    // ...

    public function configureActions(Actions $actions): Actions
    {
        // this action executes the 'renderInvoice()' method of the current CRUD controller
        $viewInvoice = Action::new('viewInvoice', 'Invoice', 'fa fa-file-invoice')
            ->linkToCrudAction('renderInvoice');

        // if the method is not defined in a CRUD controller, link to its route
        $sendInvoice = Action::new('sendInvoice', 'Send invoice', 'fa fa-envelope')
            // if the route needs parameters, you can define them:
            // 1) using an array
            ->linkToRoute('invoice_send', [
                'send_at' => (new \DateTime('+ 10 minutes'))->format('YmdHis'),
            ])

            // 2) using a callable (useful if parameters depend on the entity instance)
            // (the type-hint of the function argument is optional but useful)
            ->linkToRoute('invoice_send', function (Order $order): array {
                return [
                    'uuid' => $order->getId(),
                    'method' => $order->getUser()->getPreferredSendingMethod(),
                ];
            });

        // this action points to the invoice on Stripe application
        $viewStripeInvoice = Action::new('viewInvoice', 'Invoice', 'fa fa-file-invoice')
            ->linkToUrl(function (Order $entity) {
                return 'https://www.stripe.com/invoice/'.$entity->getStripeReference();
            });

        return $actions
            // ...
            ->add(Crud::PAGE_DETAIL, $viewInvoice)
            ->add(Crud::PAGE_DETAIL, $sendInvoice)
            ->add(Crud::PAGE_DETAIL, $viewStripeInvoice)
        ;
    }

    public function renderInvoice(AdminContext $context)
    {
        $order = $context->getEntity()->getInstance();

        // add your logic here...
    }
}

提示

EasyAdmin 中的 CRUD 控制器扩展了 Symfony 基础控制器类。当操作定义为 CRUD 控制器的方法时,它们可以使用常规 Symfony 控制器 中可用的任何快捷方式和实用程序,例如 `$this->render()`、`$this->redirect()` 等。

自定义操作可以定义 `#[AdminAction]` 属性来自定义其路由名称、路径和方法

1
2
3
4
5
6
7
8
9
use EasyCorp\Bundle\EasyAdminBundle\Attribute\AdminAction;
// ...


#[AdminAction(routePath: '/invoice', routeName: 'view_invoice', methods: ['GET', 'POST'])]
public function renderInvoice(AdminContext $context)
{
    // ...
}

全局操作

在列出条目的页面(例如 `Crud::PAGE_INDEX`)上,您可以配置每个条目的操作以及全局操作。全局操作显示在列出的条目上方。

创建自定义操作并将其全局添加到 `index` 页面的示例

1
2
3
4
5
6
$goToStripe = Action::new('goToStripe')
    ->linkToUrl('https://www.stripe.com/')
    ->createAsGlobalAction()
;

$actions->add(Crud::PAGE_INDEX, $goToStripe);

批量操作

批量操作是一种特殊的操作,它同时应用于多个项目。它们仅在 `index` 页面中可用。

假设您使用 `User` 实体管理用户,并且常见的任务是批准他们的注册。与其像前面的章节中解释的那样创建正常的 `approve` 操作,不如创建一个批量操作以提高效率并一次批准多个用户。

首先,使用 `addBatchAction()` 方法将其添加到您的操作配置中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
namespace App\Controller\Admin;

use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;

class UserCrudController extends AbstractCrudController
{
    // ...

    public function configureActions(Actions $actions): Actions
    {
        return $actions
            // ...
            ->addBatchAction(Action::new('approve', 'Approve Users')
                ->linkToCrudAction('approveUsers')
                ->addCssClass('btn btn-primary')
                ->setIcon('fa fa-user-check'))
        ;
    }
}

批量操作支持与其他操作相同的配置选项,它们可以链接到 CRUD 控制器方法、Symfony 路由或某些 URL。如果至少有一个批量操作,后端界面将更新以添加一些“复选框”,以便可以选择索引列表的多个行。

当用户单击批量操作链接/按钮时,将使用 `POST` 方法将表单提交到操作或在操作中配置的路由。获取提交数据的最简单方法是使用 `EasyCorp\Bundle\EasyAdminBundle\Dto\BatchActionDto` 类对批量操作方法的某些参数进行类型提示。如果您这样做,EasyAdmin 将注入一个包含所有批量操作数据的 DTO

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
namespace App\Controller\Admin;

use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Dto\BatchActionDto;

class UserCrudController extends AbstractCrudController
{
    // ...

    public function approveUsers(BatchActionDto $batchActionDto)
    {
        $className = $batchActionDto->getEntityFqcn();
        $entityManager = $this->container->get('doctrine')->getManagerForClass($className);
        foreach ($batchActionDto->getEntityIds() as $id) {
            $user = $entityManager->find($className, $id);
            $user->approve();
        }

        $entityManager->flush();

        return $this->redirectToRoute('admin_user_index');
    }
}

注意

作为替代方案,除了注入 `BatchActionDto` 变量外,您还可以注入 Symfony 的 `Request` 对象以获取所有原始提交的批量数据(例如 `$request->request->all('batchActionEntityIds')`)。

集成 Symfony 操作

如果操作逻辑很小并且直接与后端相关,则可以将其添加到 CRUD 控制器,因为这大大简化了其在 EasyAdmin 中的集成。但是,有时您的某些逻辑过于复杂或在 Symfony 应用程序的其他部分中使用,因此您无法将其移动到 CRUD 控制器。本节介绍如何将现有的 Symfony 操作集成到 EasyAdmin 中,以便您可以重用后端布局、菜单和其他功能。

假设您的 Symfony 应用程序具有计算有关客户的一些业务统计信息(平均订单金额、年度购买次数等)的操作。所有这些都在 `BusinessStatsCalculator` 服务中计算,因此您无法创建 CRUD 控制器来显示该信息。相反,创建一个名为 `BusinessStatsController` 的普通 Symfony 控制器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// src/Controller/Admin/BusinessStatsController.php
namespace App\Controller\Admin;

use App\Stats\BusinessStatsCalculator;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;

#[IsGranted('ROLE_ADMIN')]
class BusinessStatsController extends AbstractController
{
    public function __construct(BusinessStatsCalculator $businessStatsCalculator)
    {
        $this->businessStatsCalculator = $businessStatsCalculator;
    }

    #[Route("/admin/business-stats", name: "admin_business_stats")]
    public function index()
    {
        return $this->render('admin/business_stats/index.html.twig', [
            'data' => $this->businessStatsCalculator->getStatsSummary(),
        ]);
    }

    #[Route("/admin/business-stats/{id}", name: "admin_business_stats_customer")]
    public function customer(Customer $customer)
    {
        return $this->render('admin/business_stats/customer.html.twig', [
            'data' => $this->businessStatsCalculator->getCustomerStats($customer),
        ]);
    }
}

这是一个普通的 Symfony 控制器(它不扩展任何 EasyAdmin 类),其中包含一些逻辑,用于在 Twig 模板中呈现结果(稍后将显示)。将此控制器集成到您的 EasyAdmin 后端的第一步是使用 `configureMenuItems()` 方法将其添加到主菜单中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// src/Controller/Admin/DashboardController.php
namespace App\Controller\Admin;

use EasyCorp\Bundle\EasyAdminBundle\Attribute\AdminDashboard;
use EasyCorp\Bundle\EasyAdminBundle\Config\Dashboard;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController;

#[AdminDashboard(routePath: '/admin', routeName: 'admin')]
class DashboardController extends AbstractDashboardController
{
    // ...

    public function configureMenuItems(): iterable
    {
        // ...

        yield MenuItem::linktoRoute('Stats', 'fa fa-chart-bar', 'admin_business_stats');
    }
}

如果您重新加载后端并单击该新菜单项,您将看到一个错误,因为 BusinessStatsController 使用的模板尚未创建。查看页面的 URL,您将看到 EasyAdmin 用来集成 Symfony 操作的技巧。

生成的 URL 不是预期的 `/admin/business-stats` 清晰 URL,而是 `/admin?menuIndex=...&submenuIndex=...&routeName=admin_business_stats`。这是一个管理 URL,因此 EasyAdmin 可以创建管理上下文,加载适当的菜单等。但是,由于 `routeName` 查询字符串参数,EasyAdmin 知道它必须将请求转发到为该路由提供服务的 Symfony 控制器,并透明地为您执行此操作。

注意

以这种方式处理路由参数在大多数情况下都很好。但是,有时您需要将路由参数作为正确的 Symfony 路由参数处理。例如,如果您要传递 Symfony 模拟功能的 `_switch_user` 查询参数,您可以这样做

1
2
3
4
5
6
7
8
9
// you can generate the full URL with Symfony's URL generator:
$impersonate = Action::new('impersonate')->linkToUrl(
    $urlGenerator->generate('admin', ['_switch_user' => 'user@example.com'], UrlGeneratorInterface::ABSOLUTE_URL)
);

// or you can add the query string parameter directly:
$impersonate = Action::new('impersonate')
    ->linkToRoute('some_route')
    ->setQueryParameter('_switch_user', 'user@example.com');

现在,创建 `index()` 方法使用的模板,该模板列出了所有客户的统计摘要,并包含指向其中每个客户的详细统计信息的链接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{# templates/admin/business_stats/index.html.twig #}
{% extends '@EasyAdmin/page/content.html.twig' %}

{% block content_title 'Business Stats' %}
{% block main %}
    <table>
        <thead> {# ... #} </thead>
        <tbody>
            {% for customer_data in data %}
                <tr>
                    {# ... #}

                    <td>
                        <a href="{{ ea_url().setRoute('admin_business_stats_customer', { id: customer_data.id }) }}">
                            View Details
                        </a>
                    </td>
                </tr>
            {% endfor %}
        </tbody>
    </table>
{% endblock %}

Twig 模板扩展了 EasyAdmin 提供的 内容页面模板,以重用所有后端设计。模板的其余部分是普通的 Twig 代码,除了 URL 生成。您必须使用 ea_url() 函数并传递 Symfony 路由名称和参数,而不是使用 Symfony 的 `path()` 函数。

与之前发生的情况类似,生成的 URL 不是预期的 `/admin/business-stats/5`,而是 `/admin?routeName=admin_business_stats_customer&routeParams%5Bid%5D=5`。但这没关系。EasyAdmin 将运行您的 BusinessStatsController 的 `customer()` 方法,因此您可以呈现另一个包含客户统计信息的 Twig 模板。

生成集成在 EasyAdmin 中的 Symfony 操作的 URL

如前一节详细解释的那样,在 EasyAdmin 后端集成 Symfony 操作时,您需要以稍微不同的方式生成 URL。您必须使用 EasyAdmin 提供的 AdminUrlGenerator 服务,而不是使用 Symfony 的 UrlGenerator 服务或控制器中的 `$this->generateUrl()` 快捷方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// src/Controller/SomeController.php
namespace App\Controller;

use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class SomeController extends AbstractController
{
    private $adminUrlGenerator;

    public function __construct(AdminUrlGenerator $adminUrlGenerator)
    {
        $this->adminUrlGenerator = $adminUrlGenerator;
    }

    public function someMethod()
    {
        $url = $this->adminUrlGenerator->setRoute('admin_business_stats_customer', [
            'id' => $this->getUser()->getId(),
        ])->generateUrl();

        // ...
    }
}
这项工作,包括代码示例,均根据 Creative Commons BY-SA 3.0 许可获得许可。
目录
    版本