imt/data-grid

该库提供了一个简单、强大且完全可定制的工具,用于生成数据绑定网格

0.9.0 2013-06-17 09:42 UTC

This package is not auto-updated.

Last update: 2024-09-23 10:24:10 UTC


README

Build Status Coverage Status Dependencies Status

IMTDataGrid

概览

该库提供了一个简单、强大且完全可定制的工具,用于将服务器上的数据绑定到客户端的网格。库本身不提供任何在客户端渲染网格的工具。因此,您需要自行选择一个库来在客户端渲染网格(例如 jqGrid)。然而,该库提供了创建网格对象的机会,该对象包含名称、选项和列的集合。因此,您可以使用此对象来简化客户端网格的渲染。

安装

1. 使用Composer(推荐)

要使用Composer安装IMTDataGrid,只需将以下内容添加到您的composer.json文件中

{
    "require": {
        "imt/data-grid": "0.9.*"
    }
}

然后,您可以通过在您的composer.json文件所在的目录中运行Composer的更新命令来安装新的依赖项

$ php composer.phar update imt/data-grid

现在,Composer将自动下载所有必需的文件,并为您安装它们。

使用方法

假设您正在构建一个简单的博客,并且需要在后端有一个网格来显示帖子的信息。

进一步假设您打算使用jqGrid库在客户端渲染网格,以及Doctrine ORM作为数据源。

要开始,您需要构造一个反映帖子信息的网格对象。为了构造此对象,您需要创建一个负责创建网格的网格构建器

<?php
namespace Acme\PostBundle\DataGrid\Builder;

use Symfony\Component\Routing\RouterInterface;

use Doctrine\ORM\EntityManager;

use IMT\DataGrid\Builder\AbstractBuilder;
use IMT\DataGrid\Column\Column;
use IMT\DataGrid\DataSource\Doctrine\ORM\DataSource;

class PostBuilder extends AbstractBuilder
{
    /**
     * @var EntityManager
     */
    protected $entityManager;

    /**
     * @var RouterInterface
     */
    protected $router;

    /**
     * The constructor method
     *
     * @param RouterInterface $router
     * @param EntityManager   $entityManager
     */
    public function __construct(
        RouterInterface $router,
        EntityManager $entityManager
    ) {
        $this->router        = $router;
        $this->entityManager = $entityManager;
    }

    /**
     * {@inheritDoc}
     */
    public function buildColumns()
    {
        $this
            ->dataGrid
            ->addColumn(
                new Column(
                    array(
                        'index' => 'p.id',
                        'label' => 'Id',
                        'name'  => 'post_id',
                    )
                )
            )
            ->addColumn(
                new Column(
                    array(
                        'index' => 'p.title',
                        'label' => 'Title',
                        'name'  => 'title',
                    )
                )
            );
    }

    /**
     * {@inheritDoc}
     */
    public function buildDataSource()
    {
        $queryBuilder = $this
            ->entityManager
            ->createQueryBuilder()
            ->select(
                'p',
                'p.id AS post_id',
                'p.title'
            )
            ->from('AcmePostBundle:Post', 'p');

        $this->dataGrid->setDataSource(new DataSource($queryBuilder));
    }

    /**
     * {@inheritDoc}
     */
    public function buildOptions()
    {
        $this
            ->dataGrid
            ->setName('posts')
            ->setOptions(
                array(
                    'caption'  => 'Posts',
                    'datatype' => 'json',
                    'mtype'    => 'get',
                    'pager'    => '#posts_pager',
                    'rowList'  => array(
                        10,
                        20,
                        30,
                    ),
                    'rowNum'   => 10,
                    'url'      => $this
                        ->router
                        ->generate('acme_post_post_get_posts'),
                )
            );
    }
}

构造函数中的列对象接受一个选项数组。有四个选项:indexlabelnametemplate。前三个是必需的。如果需要,您还可以传递更多选项。例如,如果需要,可以将它们传递到客户端库中。

剩下的就是获取控制器中的网格管理器,并使用网格构建器构建网格

<?php
namespace Acme\PostBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

use IMT\DataGrid\HttpFoundation\JqGridRequest;

use Acme\PostBundle\DataGrid\Builder\PostBuilder;

class PostController extends Controller
{
    /**
     * @Method("GET")
     * @Route("/posts/", name="acme_post_post_get_posts")
     * @Template("AcmePostBundle:Post:list.html.twig")
     */
    public function getPostsAction(Request $request)
    {
        $dataGrid = $this
            ->getDataGridManager()
            ->setBuilder(
                new PostBuilder(
                    $this->getRouter(),
                    $this->getDoctrine()->getEntityManager()
                )
            )
            ->buildDataGrid()
            ->getDataGrid();

        if ($request->isXmlHttpRequest()) {
            $dataGrid->bindRequest(new JqGridRequest($request));

            return new Response(
                json_encode($dataGrid->getData()),
                200,
                array(
                    'Content-Type' => 'application/json',
                )
            );
        }

        return array(
            'dataGrid' => $dataGrid->createView(),
        );
    }

    /**
     * @return \IMT\DataGrid\Manager\ManagerInterface
     */
    private function getDataGridManager()
    {
        return $this->get('imt_data_grid.manager');
    }

    /**
     * @return \Symfony\Component\Routing\RouterInterface
     */
    private function getRouter()
    {
        return $this->get('router');
    }
}

由于指定了网格的url选项,在客户端渲染网格后,将向服务器发送额外的请求以检索数据。因此,您需要将请求与网格绑定。

一旦使用网格构建器构建了网格,您需要调用createView方法来创建网格视图对象。您可以将此对象传递到模板中,以配置客户端网格的渲染

{# in AcmePostBundle:Post:list.html.twig #}
{% extends '::base.html.twig' %}

{% block stylesheets %}
    {{ parent() }}

    {% stylesheets
        filter='?cssrewrite,?yui_css'
        output='css/jqGrid.css'
        '@AcmePostBundle/Resources/public/js/lib/jqGrid/4.4.5/css/ui.jqgrid.css'
    %}
        <link rel="stylesheet" href="{{ asset_url }}" />
    {% endstylesheets %}
{% endblock %}

{% block body %}
    <table id="{{ dataGrid.getName }}"><tr><td/></tr></table>
    <div id="{{ dataGrid.getName }}_pager"></div>
{% endblock %}

{% block javascripts %}
    {{ parent() }}

    {% javascripts
         filter='?yui_js'
         output='js/jqGrid.js'
        '@AcmePostBundle/Resources/public/js/lib/jqGrid/4.4.5/js/i18n/grid.locale-en.js'
        '@AcmePostBundle/Resources/public/js/lib/jqGrid/4.4.5/js/jquery.jqGrid.min.js'
    %}
        <script src="{{ asset_url }}"></script>
    {% endjavascripts %}

    <script>
        {% set colModel = [] %}
        {% set colNames = [] %}
        {% for column in dataGrid.getColumns %}
            {% set colModel = colModel|merge([column.toArray]) %}
            {% set colNames = colNames|merge([column.get('label')]) %}
        {% endfor %}

        {% set options = dataGrid.getOptions %}
        {% set options = options|merge({'colModel':colModel}) %}
        {% set options = options|merge({'colNames':colNames}) %}

        $(function(){
            $('#' + '{{ dataGrid.getName }}').jqGrid({{ options|json_encode|raw }});
            $('#' + '{{ dataGrid.getName }}').jqGrid('filterToolbar',{stringResult:true});
            $('#' + '{{ dataGrid.getName }}').jqGrid('navGrid','{{ '#' ~ dataGrid.getName ~ '_pager' }}');
        });
    </script>
{% endblock %}

就是这样。您应该在客户端看到包含帖子信息的网格。如您所见,创建一个与服务器上的数据绑定的网格并具有搜索功能非常简单。

测试

$ make test

贡献

有关详细信息,请参阅CONTRIBUTING

鸣谢

许可证

该库在MIT许可证下发布。请参阅随源代码一起分发的LICENSE文件中的完整许可证。