OroPlatform:网格行上的自定义操作

Posted

技术标签:

【中文标题】OroPlatform:网格行上的自定义操作【英文标题】:OroPlatform: Custom action on the grid rows 【发布时间】:2021-12-03 03:18:33 【问题描述】:

上下文

我目前正在处理一个 OroPlatform 项目,我需要添加一个操作以从 OroPlatform 网格下载文件:

这是我已经做过的:

# datagrids.yml
  business-unit-grid:
    properties:
      getpdf_link:
        type: url
        route: baltimore_action_pdf
        params:
          - id
    actions:
      getpdf:
        type: getpdf
        label: "Export garanties"
        data_identifier: u.id
        entity_name: Oro\Bundle\OrganizationBundle\Entity\BusinessUnit
        icon: file
        link: getpdf_link

<?php

namespace Baltimore\Bundle\AppBundle\Extension\Action\Actions;

use Oro\Bundle\DataGridBundle\Extension\Action\Actions\AjaxAction;

class GetPdfAction extends AjaxAction

    /**
     * @var array
     */
    protected $requiredOptions = ['entity_name', 'data_identifier'];

    public function getOptions()
    
        $options = parent::getOptions();
        $options['frontend_type'] = 'getpdf';
        if (empty($options['frontend_handle'])) 
            $options['frontend_handle'] = 'getpdf';
        
        return $options;
    

<?php

namespace Baltimore\Bundle\AppBundle\Controller\Actions;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\Request;
use Dompdf\Dompdf;
use Dompdf\Options;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;

/**
 * @Route("/action")
 */
class ActionController extends Controller

    /**
     * @Route("/pdfexport/id", requirements="id"="\d+", name="baltimore_action_pdf", methods="GET", "POST")
     */
    public function actionPdf(Request $request)
    
        //dump($request->get('id'));

        $pdfOptions = new Options();
        $pdfOptions->set('defaultFont', 'Arial');

        // Instantiate Dompdf with our options
        $dompdf = new Dompdf($pdfOptions);

        // Retrieve the html generated in our twig file
        $html = $this->renderView('BaltimoreAppBundle:pdf:mypdf.html.twig', [
            'title' => "Welcome to our PDF Test"
        ]);

        // Load HTML to Dompdf
        $dompdf->loadHtml($html);

        // (Optional) Setup the paper size and orientation 'portrait' or 'portrait'
        $dompdf->setPaper('A4', 'portrait');

        // Render the HTML as PDF
        $dompdf->render();

        // Output the generated PDF to Browser (force download)
        $dompdf->stream("mypdf.pdf", [
            "Attachment" => true
        ]);

        exit;
    

为了确保错误不是来自我的控制器,我在经典控制器中创建了相同的方法并且这个方法有效。

    /**
     * @Route("/download", name="app_vehicule_download")
     */
    public function downloadAction()
    
        // Configure Dompdf according to your needs
        $pdfOptions = new Options();
        $pdfOptions->set('defaultFont', 'Arial');

        // Instantiate Dompdf with our options
        $dompdf = new Dompdf($pdfOptions);

        // Retrieve the HTML generated in our twig file
        $html = $this->renderView('BaltimoreAppBundle:pdf:mypdf.html.twig', [
            'title' => "Welcome to our PDF Test"
        ]);

        // Load HTML to Dompdf
        $dompdf->loadHtml($html);

        // (Optional) Setup the paper size and orientation 'portrait' or 'portrait'
        $dompdf->setPaper('A4', 'portrait');

        // Render the HTML as PDF
        $dompdf->render();

        // Output the generated PDF to Browser (force download)
        $dompdf->stream("mypdf.pdf", [
            "Attachment" => true
        ]);

        exit;
    

问题

一切正常,自定义按钮在网格中可用,我可以发送 JSON 响应。但是,当我想创建一个下载 PDF 的方法时,我遇到了错误。

当我在经典控制器中使用我的代码时,它可以工作。似乎这与需要 JSON 响应作为返回类型的 ajax 操作有关..

【问题讨论】:

【参考方案1】:

我终于找到了解决此问题的解决方案。我敢肯定这不是最优雅的方式,但是......它有效。

这是我所做的:

我更改了自定义扩展操作类
<?php

namespace Baltimore\Bundle\AppBundle\Extension\Action\Actions;

use Oro\Bundle\DataGridBundle\Extension\Action\ActionConfiguration;
use Oro\Bundle\DataGridBundle\Extension\Action\Actions\AbstractAction;

class GetPdfAction extends AbstractAction

    /**
     * @var array
     */
    protected $requiredOptions = ['entity_name', 'data_identifier', 'link'];

    /**
     * @param ActionConfiguration $options
     */
    public function setOptions(ActionConfiguration $options)
    
        parent::setOptions($options);
    

然后,我更改了与我的自定义操作对应的 JS 操作
define([
    'oro/datagrid/action/model-action'
], function(ModelAction) 
    'use strict';

    /**
     * GetPDF action
     *
     * @export  oro/datagrid/action/getpdf-action
     * @class   oro.datagrid.action.GetPdfAction
     * @extends oro.datagrid.action.ModelAction
     */
    const GetPdfAction = ModelAction.extend(

        /**
         * @inheritDoc
         */
        constructor: function GetPdfAction(options) 
            GetPdfAction.__super__.constructor.call(this, options);
        ,

        /**
         * Execute download file
         */
        execute: function() 
            this.downloadFile(this.messages);
        ,

        /**
         * PDF download
         */
        downloadFile: function() 
            const host = window.location.protocol + '//' + window.location.host;
            const link = document.createElement('a'), filename = 'file.pdf';

            link.href = host + this.getLink();
            link.download = filename;
            link.click()
        
    );

    return GetPdfAction;
);

如果有人知道如何改进 JS 脚本,那将非常有趣。

【讨论】:

JS 操作已经遵循了 OroCommerce 团队的所有最佳实践。我们没有什么可抱怨的。干得好!

以上是关于OroPlatform:网格行上的自定义操作的主要内容,如果未能解决你的问题,请参考以下文章

OroPlatform:覆盖核心实体表单构建器

Datagrid上的自定义标题颜色?

在命令行上使用带有jupyter nbconvert v5.3.1的自定义预处理器

如何获得自定义网格的自定义材料

Vue.js - 带有自定义叠加层的自定义照片网格

如何自动选择操作栏上的自定义视图(EditText)?